Repository: parsa-epfl/cloudsuite Branch: main Commit: c9d7584b9f4f Files: 356 Total size: 86.5 MB Directory structure: gitextract_ld6tfyvy/ ├── .github/ │ ├── scripts/ │ │ └── build-images.sh │ └── workflows/ │ ├── build-images.yaml │ └── spell-check.yaml ├── .gitignore ├── .spellcheck.yml ├── .wordlist.txt ├── LICENSE.md ├── README.md ├── benchmarks/ │ ├── data-analytics/ │ │ └── latest/ │ │ ├── Dockerfile │ │ └── files/ │ │ ├── benchmark.sh │ │ ├── categories │ │ ├── docker-entrypoint.py │ │ └── mahout-examples-0.13.0-job.jar │ ├── data-caching/ │ │ ├── client/ │ │ │ ├── Dockerfile │ │ │ └── docker-entrypoint.sh │ │ └── server/ │ │ └── Dockerfile │ ├── data-serving/ │ │ ├── .gitignore │ │ ├── client/ │ │ │ ├── Dockerfile │ │ │ ├── load.sh │ │ │ ├── setup_tables.txt │ │ │ └── warmup.sh │ │ └── server/ │ │ ├── Dockerfile │ │ ├── README.md │ │ └── docker-entrypoint.py │ ├── data-serving-relational/ │ │ ├── client/ │ │ │ ├── Dockerfile │ │ │ ├── docker-entrypoint.py │ │ │ └── template/ │ │ │ ├── database.conf │ │ │ ├── oltp-rw.py │ │ │ └── tpcc.py │ │ └── server/ │ │ ├── Dockerfile │ │ └── docker-entrypoint.py │ ├── graph-analytics/ │ │ └── latest/ │ │ ├── Dockerfile │ │ ├── benchmark/ │ │ │ ├── build.sbt │ │ │ ├── run_benchmark.sh │ │ │ └── src/ │ │ │ └── main/ │ │ │ └── scala/ │ │ │ └── GraphAnalytics.scala │ │ └── files/ │ │ └── entrypoint.sh │ ├── in-memory-analytics/ │ │ └── latest/ │ │ ├── Dockerfile │ │ ├── files/ │ │ │ ├── entrypoint.sh │ │ │ ├── spark-defaults.conf │ │ │ └── spark-env.sh │ │ └── movielens-als/ │ │ ├── build.sbt │ │ ├── run_benchmark.sh │ │ └── src/ │ │ └── main/ │ │ └── scala/ │ │ └── MovieLensALS.scala │ ├── media-streaming/ │ │ ├── client/ │ │ │ ├── Dockerfile │ │ │ └── files/ │ │ │ ├── docker-entrypoint.sh │ │ │ ├── run/ │ │ │ │ ├── benchmark.sh │ │ │ │ ├── hostlist.client │ │ │ │ ├── hostlist.server │ │ │ │ ├── peak_hunter/ │ │ │ │ │ ├── launch_hunt_bin.sh │ │ │ │ │ └── launch_remote.sh │ │ │ │ └── process_logs.sh │ │ │ └── videoperf/ │ │ │ ├── AUTHORS │ │ │ ├── COPYRIGHT │ │ │ ├── ChangeLog │ │ │ ├── Makefile │ │ │ ├── Makefile.in │ │ │ ├── NEWS │ │ │ ├── README │ │ │ ├── README.UW/ │ │ │ │ ├── README.CALL_STATS │ │ │ │ ├── README.DYNOUT │ │ │ │ ├── README.NO_RATE_HANG │ │ │ │ ├── README.STABLE_STATS │ │ │ │ ├── README.STAGGER_START │ │ │ │ ├── README.TIMEOUT │ │ │ │ ├── README.WSESSLOG │ │ │ │ └── man-call_stats.txt │ │ │ ├── README.WINDOWS │ │ │ ├── TBB-NEW │ │ │ ├── TODO │ │ │ ├── aclocal.m4 │ │ │ ├── bt2line │ │ │ ├── call.c │ │ │ ├── call.h │ │ │ ├── config.cache │ │ │ ├── config.guess │ │ │ ├── config.h │ │ │ ├── config.h.in │ │ │ ├── config.log │ │ │ ├── config.status │ │ │ ├── config.sub │ │ │ ├── configure │ │ │ ├── configure.in │ │ │ ├── conn.c │ │ │ ├── conn.h │ │ │ ├── core.c │ │ │ ├── core.h │ │ │ ├── core_connect │ │ │ ├── event.c │ │ │ ├── event.h │ │ │ ├── gen/ │ │ │ │ ├── Makefile │ │ │ │ ├── Makefile.in │ │ │ │ ├── call_seq.c │ │ │ │ ├── conn_rate.c │ │ │ │ ├── misc.c │ │ │ │ ├── rate.c │ │ │ │ ├── rate.h │ │ │ │ ├── sess_cookie.c │ │ │ │ ├── session.c │ │ │ │ ├── session.h │ │ │ │ ├── uri_fixed.c │ │ │ │ ├── uri_wlog.c │ │ │ │ ├── uri_wset.c │ │ │ │ ├── videosesslog.c │ │ │ │ ├── videosesslog.h │ │ │ │ ├── wsess.c │ │ │ │ └── wsesspage.c │ │ │ ├── http.c │ │ │ ├── http.h │ │ │ ├── httperf.c │ │ │ ├── httperf.h │ │ │ ├── httperf.man │ │ │ ├── idleconn.c │ │ │ ├── install-sh │ │ │ ├── lib/ │ │ │ │ ├── COPYING.txt │ │ │ │ ├── Makefile │ │ │ │ ├── Makefile.in │ │ │ │ ├── README │ │ │ │ ├── getopt.c │ │ │ │ ├── getopt.h │ │ │ │ ├── getopt1.c │ │ │ │ └── ssl_writev.c │ │ │ ├── mkinstalldirs │ │ │ ├── notes.txt │ │ │ ├── object.c │ │ │ ├── object.h │ │ │ ├── out_1080p_0.txt │ │ │ ├── output.log │ │ │ ├── run-httperf │ │ │ ├── sess.c │ │ │ ├── sess.h │ │ │ ├── stat/ │ │ │ │ ├── Makefile │ │ │ │ ├── Makefile.in │ │ │ │ ├── basic.c │ │ │ │ ├── call_stats.c │ │ │ │ ├── call_stats.h │ │ │ │ ├── print_reply.c │ │ │ │ ├── sess_stat.c │ │ │ │ ├── spec_stats.c │ │ │ │ ├── spec_stats.h │ │ │ │ └── stats.h │ │ │ ├── sys_sched_affinity.c │ │ │ ├── sys_sched_affinity.h │ │ │ ├── tags │ │ │ ├── timeout │ │ │ ├── timer.c │ │ │ ├── timer.h │ │ │ └── ttest.c │ │ ├── dataset/ │ │ │ ├── Dockerfile │ │ │ ├── bootstrap.sh │ │ │ └── files/ │ │ │ ├── download_video_files.sh │ │ │ └── filegen/ │ │ │ ├── Makefile │ │ │ ├── gen_fileset.c │ │ │ ├── generate_video_files_and_logs.sh │ │ │ ├── make_zipf.c │ │ │ ├── params/ │ │ │ │ ├── 240p │ │ │ │ ├── 360p │ │ │ │ ├── 480p │ │ │ │ └── 720p │ │ │ └── video_gen.py │ │ └── server/ │ │ ├── Dockerfile │ │ ├── entrypoint.sh │ │ └── files/ │ │ ├── HTMLWebPlayer/ │ │ │ ├── index.html │ │ │ └── js/ │ │ │ └── helper.js │ │ ├── limits.conf.append │ │ └── nginx.location.append │ ├── web-search/ │ │ ├── client/ │ │ │ ├── Dockerfile │ │ │ ├── docker-entrypoint.py │ │ │ └── files/ │ │ │ └── search/ │ │ │ ├── LICENSE │ │ │ ├── build.properties │ │ │ ├── build.xml │ │ │ ├── config/ │ │ │ │ ├── logging.properties │ │ │ │ └── security/ │ │ │ │ └── driver.policy │ │ │ ├── src/ │ │ │ │ └── sample/ │ │ │ │ └── searchdriver/ │ │ │ │ ├── terms_ordered │ │ │ │ ├── terms_original │ │ │ │ ├── terms_random │ │ │ │ └── terms_shuffled │ │ │ └── template/ │ │ │ ├── Random.java.in │ │ │ ├── Zipfian.java.in │ │ │ ├── head.java.in │ │ │ └── run.xml.in │ │ ├── dataset/ │ │ │ ├── Dockerfile │ │ │ └── docker-entrypoint.sh │ │ ├── index/ │ │ │ ├── Dockerfile │ │ │ ├── entrypoint.sh │ │ │ ├── files/ │ │ │ │ ├── nutch-default.xml │ │ │ │ ├── schema.xml │ │ │ │ ├── seed.txt │ │ │ │ └── solrconfig.xml │ │ │ └── generate_index.sh │ │ └── server/ │ │ ├── Dockerfile │ │ ├── docker-entrypoint.sh │ │ └── files/ │ │ ├── limits.txt │ │ ├── query.sh │ │ ├── schema.xml │ │ └── solrconfig.xml │ └── web-serving/ │ ├── db_server/ │ │ ├── Dockerfile │ │ └── entrypoint.sh │ ├── faban_client/ │ │ ├── Dockerfile │ │ └── files/ │ │ ├── commons-codec-1.2.jar │ │ ├── commons-httpclient-3.1.jar │ │ ├── commons-logging.jar │ │ ├── fabanagents.jar │ │ ├── fabancommon.jar │ │ ├── fabandriver.jar │ │ ├── users.list │ │ ├── usersetup.properties │ │ └── web20_benchmark/ │ │ ├── .classpath │ │ ├── .gitignore │ │ ├── .metadata/ │ │ │ ├── .mylyn/ │ │ │ │ └── .taskListIndex/ │ │ │ │ ├── segments.gen │ │ │ │ └── segments_1 │ │ │ ├── .plugins/ │ │ │ │ ├── org.eclipse.core.resources/ │ │ │ │ │ ├── .root/ │ │ │ │ │ │ └── .indexes/ │ │ │ │ │ │ ├── history.version │ │ │ │ │ │ ├── properties.index │ │ │ │ │ │ └── properties.version │ │ │ │ │ └── .safetable/ │ │ │ │ │ └── org.eclipse.core.resources │ │ │ │ ├── org.eclipse.core.runtime/ │ │ │ │ │ └── .settings/ │ │ │ │ │ ├── org.eclipse.core.resources.prefs │ │ │ │ │ ├── org.eclipse.jdt.ui.prefs │ │ │ │ │ ├── org.eclipse.m2e.discovery.prefs │ │ │ │ │ ├── org.eclipse.mylyn.context.core.prefs │ │ │ │ │ ├── org.eclipse.mylyn.monitor.ui.prefs │ │ │ │ │ ├── org.eclipse.mylyn.tasks.ui.prefs │ │ │ │ │ ├── org.eclipse.team.cvs.ui.prefs │ │ │ │ │ ├── org.eclipse.team.ui.prefs │ │ │ │ │ ├── org.eclipse.ui.ide.prefs │ │ │ │ │ ├── org.eclipse.ui.prefs │ │ │ │ │ └── org.eclipse.ui.workbench.prefs │ │ │ │ ├── org.eclipse.e4.workbench/ │ │ │ │ │ └── workbench.xmi │ │ │ │ ├── org.eclipse.jdt.core/ │ │ │ │ │ ├── assumedExternalFilesCache │ │ │ │ │ ├── externalFilesCache │ │ │ │ │ ├── invalidArchivesCache │ │ │ │ │ └── nonChainingJarsCache │ │ │ │ ├── org.eclipse.jdt.ui/ │ │ │ │ │ ├── OpenTypeHistory.xml │ │ │ │ │ ├── QualifiedTypeNameHistory.xml │ │ │ │ │ └── dialog_settings.xml │ │ │ │ ├── org.eclipse.m2e.logback.configuration/ │ │ │ │ │ ├── 0.log │ │ │ │ │ └── logback.1.5.1.20150109-1820.xml │ │ │ │ ├── org.eclipse.ui.ide/ │ │ │ │ │ └── dialog_settings.xml │ │ │ │ └── org.eclipse.ui.workbench/ │ │ │ │ ├── dialog_settings.xml │ │ │ │ └── workingsets.xml │ │ │ └── version.ini │ │ ├── .project │ │ ├── .settings/ │ │ │ └── org.eclipse.jdt.core.prefs │ │ ├── build/ │ │ │ ├── Usergen.jar │ │ │ ├── Web20Driver.jar │ │ │ ├── classes/ │ │ │ │ ├── users.txt │ │ │ │ └── users.xml │ │ │ ├── commons-codec-1.2.jar │ │ │ ├── commons-httpclient-3.1.jar │ │ │ ├── commons-logging.jar │ │ │ ├── fabanagents.jar │ │ │ ├── fabancommon.jar │ │ │ ├── fabandriver.jar │ │ │ └── lib/ │ │ │ └── Web20Driver.jar │ │ ├── build.properties │ │ ├── build.xml │ │ ├── config/ │ │ │ └── logging.properties │ │ ├── deploy/ │ │ │ ├── benchmark.xml │ │ │ └── run.xml │ │ ├── lib/ │ │ │ ├── commons-codec-1.2.jar │ │ │ ├── commons-httpclient-3.1.jar │ │ │ ├── commons-logging.jar │ │ │ ├── fabanagents.jar │ │ │ ├── fabancommon.jar │ │ │ └── fabandriver.jar │ │ ├── run/ │ │ │ ├── entrypoint.sh │ │ │ └── gen │ │ ├── src/ │ │ │ ├── org/ │ │ │ │ └── json/ │ │ │ │ ├── CDL.java │ │ │ │ ├── Cookie.java │ │ │ │ ├── CookieList.java │ │ │ │ ├── HTTP.java │ │ │ │ ├── HTTPTokener.java │ │ │ │ ├── JSONArray.java │ │ │ │ ├── JSONException.java │ │ │ │ ├── JSONML.java │ │ │ │ ├── JSONObject.java │ │ │ │ ├── JSONString.java │ │ │ │ ├── JSONStringer.java │ │ │ │ ├── JSONTokener.java │ │ │ │ ├── JSONWriter.java │ │ │ │ ├── Property.java │ │ │ │ ├── README │ │ │ │ ├── XML.java │ │ │ │ └── XMLTokener.java │ │ │ ├── setup/ │ │ │ │ └── UserGenerator.java │ │ │ ├── users.txt │ │ │ ├── users.xml │ │ │ ├── usersetup.properties │ │ │ └── workload/ │ │ │ ├── driver/ │ │ │ │ ├── RandomStringGenerator.java │ │ │ │ ├── UserPasswordPair.java │ │ │ │ ├── Web20Client.java │ │ │ │ ├── Web20Driver.java │ │ │ │ └── Web20Driver.java.in │ │ │ └── harness/ │ │ │ └── ElggBenchmark.java │ │ └── users.list │ ├── memcached_server/ │ │ └── Dockerfile │ └── web_server/ │ ├── Dockerfile │ ├── bootstrap.sh │ └── files/ │ ├── limits.conf.append │ ├── nginx_sites_avail_pt.append │ ├── nginx_sites_avail_tls.append │ ├── repos.append │ └── settings_4.3.php ├── commons/ │ ├── base-os/ │ │ ├── Dockerfile.amd64 │ │ ├── Dockerfile.arm64 │ │ ├── Dockerfile.riscv64 │ │ └── build.sh │ ├── cassandra/ │ │ ├── 3.11.6/ │ │ │ ├── Dockerfile │ │ │ └── jvm.options │ │ └── 4.1.0/ │ │ ├── Dockerfile │ │ └── install.sh │ ├── faban/ │ │ └── 1.4/ │ │ └── Dockerfile │ ├── hadoop/ │ │ ├── 2.10.2/ │ │ │ ├── Dockerfile │ │ │ └── files/ │ │ │ ├── core-site.xml.template │ │ │ ├── entrypoint.sh │ │ │ ├── example_benchmark.sh │ │ │ ├── hadoop-start.py │ │ │ ├── hdfs-site.xml.template │ │ │ ├── mapred-site.xml.template │ │ │ └── yarn-site.xml.template │ │ └── 3.3.4/ │ │ ├── Dockerfile │ │ └── files/ │ │ ├── core-site.xml.template │ │ ├── hadoop-start.py │ │ ├── hdfs-site.xml.template │ │ ├── mapred-site.xml.template │ │ └── yarn-site.xml.template │ ├── java/ │ │ ├── openjdk11/ │ │ │ └── Dockerfile │ │ └── openjdk17/ │ │ └── Dockerfile │ ├── memcached/ │ │ ├── 1.6.10/ │ │ │ └── Dockerfile │ │ └── 1.6.15/ │ │ └── Dockerfile │ ├── mysql/ │ │ └── mariadb-10.6/ │ │ ├── Dockerfile │ │ ├── bootstrap.sh │ │ └── files/ │ │ └── execute.sh │ ├── postgresql/ │ │ └── 15/ │ │ └── Dockerfile │ └── spark/ │ ├── 2.4.5/ │ │ ├── Dockerfile │ │ └── files/ │ │ ├── entrypoint.sh │ │ ├── start-master-fg.sh │ │ └── start-worker-fg.sh │ └── 3.3.2/ │ ├── Dockerfile │ └── files/ │ ├── entrypoint.sh │ ├── start-master-fg.sh │ └── start-worker-fg.sh ├── datasets/ │ ├── movielens-dataset/ │ │ └── latest/ │ │ ├── .gitignore │ │ ├── Dockerfile │ │ └── files/ │ │ └── myratings.csv │ ├── twitter-dataset-graph/ │ │ └── latest/ │ │ └── Dockerfile │ └── wikimedia-pages-dataset/ │ └── latest/ │ └── Dockerfile └── docs/ ├── benchmarks/ │ ├── data-analytics.md │ ├── data-caching.md │ ├── data-serving-relational.md │ ├── data-serving.md │ ├── graph-analytics.md │ ├── in-memory-analytics.md │ ├── media-streaming.md │ ├── web-search.md │ └── web-serving.md ├── buildx.md └── datasets/ └── movielens-dataset.md ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/scripts/build-images.sh ================================================ #!/bin/bash # @authors: Somya Arora, Arash Pourhabibi # @modified: Shanqing Lin, Ali Ansari # 1. Figure out the modified files if [ "${GITHUB_EVENT_NAME}" = "pull_request" ]; then modified_files=$(git --no-pager diff --name-only ${PR_COMMIT_RANGE}) else modified_files=$(git --no-pager diff --name-only ${PUSH_COMMIT_RANGE}) fi # 2.Get benchmark name and tag name for this build image_name=${DH_REPO#*/} tag_name=$IMG_TAG if [ -z "$modified_files" ]; then echo "No Modifications required." else echo "Checking against modified files" fi # 3.Find out whether the files related with the current build were modified or not if (grep -q "${DF_PATH#./}" <<<$modified_files) || # Rebuild the image if any file in the build folder is changed (grep -q "build-images.sh" <<<$modified_files) || (grep -q "build-images.yaml" <<<$modified_files) || [ "${IS_PARENT_MODIFIED}" = "true" ]; then # if modified, then rebuild their docker image # remove build cache docker buildx prune -a -f # install QEMU for extra arch arch_list=${DBX_PLATFORM//linux\//} # linux/amd64,linux/arm64,linux/riscv64 -> amd64,arm64,riscv64 echo "Platforms: ${arch_list}" extra_arch_list=${arch_list#amd64} # amd64,arm64,riscv64 -> ,arm64,riscv64 extra_arch_list=${extra_arch_list#,} # reference: https://github.com/tonistiigi/binfmt/ if [ $extra_arch_list ]; then docker run --rm --privileged 'tonistiigi/binfmt:latest' --install $extra_arch_list # reference: https://github.com/docker/buildx/issues/495 docker run --rm --privileged multiarch/qemu-user-static --reset -p yes docker buildx create --name multiarch --driver docker-container --use docker buildx inspect --bootstrap else echo "No extra arch is found, skipping install QEMU." fi if ( [ "${GITHUB_EVENT_NAME}" = "push" ] && [ "${GITHUB_REF}" = "refs/heads/main" ] ) || [ "${FORCE_PUSH}" = "true" ]; then docker login -u="$DOCKER_USER" -p="$DOCKER_PASS" # Pushing needs login, test if login was successful if [ $? != "0" ]; then exit 1 fi DO_PUSH="--push" fi if ([ $image_name = "base-os" ]); then cd $DF_PATH for arch in amd64 arm64 riscv64; do docker buildx build --platform=linux/${arch} -t $DH_REPO:${arch} -f Dockerfile.${arch} $DO_PUSH . if [ $? != "0" ]; then exit 1 fi if [ -n "$DO_PUSH" ]; then docker buildx imagetools create -t $DH_REPO:$IMG_TAG $DH_REPO:amd64 $DH_REPO:arm64 $DH_REPO:riscv64 fi done else docker buildx build --platform $DBX_PLATFORM -t $DH_REPO:$IMG_TAG $DO_PUSH $DF_PATH fi # make sure build was successful if [ $? != "0" ]; then exit 1 fi echo "MODIFIED=true" >> $GITHUB_ENV # if no file related to this image was modified else echo "No Modifications to this image" fi ================================================ FILE: .github/workflows/build-images.yaml ================================================ name: build-and-push-docker-image on: push: branches: - main - dev pull_request: branches: - main - dev env: PUSH_COMMIT_RANGE: ${{ github.event.before }}...${{ github.event.after }} PR_COMMIT_RANGE: ${{ github.event.pull_request.base.sha }}...${{ github.event.pull_request.head.sha }} DOCKER_USER: ${{ secrets.DOCKER_HUB_USERNAME }} DOCKER_PASS: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} FORCE_PUSH: "false" jobs: base-os: runs-on: ubuntu-latest env: DH_REPO: "cloudsuite/${{ github.job }}" DF_PATH: "./commons/base-os" DBX_PLATFORM: "linux/amd64,linux/arm64,linux/riscv64" outputs: is_parent_modified: ${{ steps.set_is_parent_modified.outputs.is_parent_modified }} steps: - name: checkout uses: actions/checkout@v3 with: fetch-depth: 0 - name: build and push run: "./.github/scripts/build-images.sh" env: IMG_TAG: "ubuntu" - id: set_is_parent_modified run: echo "is_parent_modified=${MODIFIED}" >> $GITHUB_OUTPUT java: runs-on: ubuntu-latest needs: base-os env: DH_REPO: "cloudsuite/${{ github.job }}" outputs: is_parent_modified: ${{ steps.set_is_parent_modified.outputs.is_parent_modified }} strategy: matrix: include: - tag: "openjdk11" platform: "linux/amd64,linux/arm64,linux/riscv64" - tag: "openjdk17" platform: "linux/amd64,linux/arm64,linux/riscv64" steps: - name: checkout uses: actions/checkout@v3 with: fetch-depth: 0 - if: ${{ needs.base-os.outputs.is_parent_modified == 'true' }} run: echo "IS_PARENT_MODIFIED=true" >> $GITHUB_ENV - name: build and push run: "./.github/scripts/build-images.sh" env: IMG_TAG: "${{ matrix.tag }}" DF_PATH: "./commons/${{ github.job }}/${{ matrix.tag }}" DBX_PLATFORM: ${{ matrix.platform }} - id: set_is_parent_modified run: echo "is_parent_modified=${MODIFIED}" >> $GITHUB_OUTPUT mysql: runs-on: ubuntu-latest needs: base-os env: DH_REPO: "cloudsuite/${{ github.job }}" outputs: is_parent_modified: ${{ steps.set_is_parent_modified.outputs.is_parent_modified }} strategy: matrix: tag: ["mariadb-10.6"] platform: ["linux/amd64,linux/arm64,linux/riscv64"] steps: - name: checkout uses: actions/checkout@v3 with: fetch-depth: 0 - if: ${{ needs.base-os.outputs.is_parent_modified == 'true' }} run: echo "IS_PARENT_MODIFIED=true" >> $GITHUB_ENV - name: build and push run: "./.github/scripts/build-images.sh" env: IMG_TAG: "${{ matrix.tag }}" DF_PATH: "./commons/${{ github.job }}/${{ matrix.tag }}" DBX_PLATFORM: ${{ matrix.platform }} - id: set_is_parent_modified run: echo "is_parent_modified=${MODIFIED}" >> $GITHUB_OUTPUT memcached: runs-on: ubuntu-latest needs: base-os env: DH_REPO: "cloudsuite/${{ github.job }}" outputs: is_parent_modified: ${{ steps.set_is_parent_modified.outputs.is_parent_modified }} strategy: matrix: tag: ["1.6.15"] platform: ["linux/amd64,linux/arm64,linux/riscv64"] steps: - name: checkout uses: actions/checkout@v3 with: fetch-depth: 0 - if: ${{ needs.base-os.outputs.is_parent_modified == 'true' }} run: echo "IS_PARENT_MODIFIED=true" >> $GITHUB_ENV - name: build and push run: "./.github/scripts/build-images.sh" env: IMG_TAG: "${{ matrix.tag }}" DF_PATH: "./commons/${{ github.job }}/${{ matrix.tag }}" DBX_PLATFORM: ${{ matrix.platform }} - id: set_is_parent_modified run: echo "is_parent_modified=${MODIFIED}" >> $GITHUB_OUTPUT faban: runs-on: ubuntu-latest needs: java env: DH_REPO: "cloudsuite/${{ github.job }}" outputs: is_parent_modified: ${{ steps.set_is_parent_modified.outputs.is_parent_modified }} strategy: matrix: tag: ["1.4"] platform: ["linux/amd64,linux/arm64,linux/riscv64"] steps: - name: checkout uses: actions/checkout@v3 with: fetch-depth: 0 - if: ${{ needs.java.outputs.is_parent_modified == 'true' }} run: echo "IS_PARENT_MODIFIED=true" >> $GITHUB_ENV - name: build and push run: "./.github/scripts/build-images.sh" env: IMG_TAG: "${{ matrix.tag }}" DF_PATH: "./commons/${{ github.job }}/${{ matrix.tag }}" DBX_PLATFORM: ${{ matrix.platform }} - id: set_is_parent_modified run: echo "is_parent_modified=${MODIFIED}" >> $GITHUB_OUTPUT spark: runs-on: ubuntu-latest needs: java env: DH_REPO: "cloudsuite/${{ github.job }}" outputs: is_parent_modified: ${{ steps.set_is_parent_modified.outputs.is_parent_modified }} strategy: matrix: tag: ["3.3.2"] platform: ["linux/amd64,linux/arm64,linux/riscv64"] steps: - name: checkout uses: actions/checkout@v3 with: fetch-depth: 0 - if: ${{ needs.java.outputs.is_parent_modified == 'true' }} run: echo "IS_PARENT_MODIFIED=true" >> $GITHUB_ENV - name: build and push run: "./.github/scripts/build-images.sh" env: IMG_TAG: "${{ matrix.tag }}" DF_PATH: "./commons/${{ github.job }}/${{ matrix.tag }}" DBX_PLATFORM: ${{ matrix.platform }} - id: set_is_parent_modified run: echo "is_parent_modified=${MODIFIED}" >> $GITHUB_OUTPUT cassandra: runs-on: ubuntu-latest needs: java env: DH_REPO: "cloudsuite/${{ github.job }}" outputs: is_parent_modified: ${{ steps.set_is_parent_modified.outputs.is_parent_modified }} strategy: matrix: tag: ["3.11.6"] platform: ["linux/amd64,linux/arm64,linux/riscv64"] steps: - name: checkout uses: actions/checkout@v3 with: fetch-depth: 0 - if: ${{ needs.java.outputs.is_parent_modified == 'true' }} run: echo "IS_PARENT_MODIFIED=true" >> $GITHUB_ENV - name: build and push run: "./.github/scripts/build-images.sh" env: IMG_TAG: "${{ matrix.tag }}" DF_PATH: "./commons/${{ github.job }}/${{ matrix.tag }}" DBX_PLATFORM: ${{ matrix.platform }} - id: set_is_parent_modified run: echo "is_parent_modified=${MODIFIED}" >> $GITHUB_OUTPUT hadoop: runs-on: ubuntu-latest needs: java env: DH_REPO: "cloudsuite/${{ github.job }}" outputs: is_parent_modified: ${{ steps.set_is_parent_modified.outputs.is_parent_modified }} strategy: matrix: tag: ["2.10.2", "3.3.4"] platform: ["linux/amd64,linux/arm64,linux/riscv64"] steps: - name: checkout uses: actions/checkout@v3 with: fetch-depth: 0 - if: ${{ needs.java.outputs.is_parent_modified == 'true' }} run: echo "IS_PARENT_MODIFIED=true" >> $GITHUB_ENV - name: build and push run: "./.github/scripts/build-images.sh" env: IMG_TAG: "${{ matrix.tag }}" DF_PATH: "./commons/${{ github.job }}/${{ matrix.tag }}" DBX_PLATFORM: ${{ matrix.platform }} - id: set_is_parent_modified run: echo "is_parent_modified=${MODIFIED}" >> $GITHUB_OUTPUT postgresql: runs-on: ubuntu-latest needs: base-os env: DH_REPO: "cloudsuite/${{ github.job }}" outputs: is_parent_modified: ${{ steps.set_is_parent_modified.outputs.is_parent_modified }} strategy: matrix: tag: ["15"] platform: ["linux/amd64,linux/arm64"] steps: - name: checkout uses: actions/checkout@v3 with: fetch-depth: 0 - if: ${{ needs.java.outputs.is_parent_modified == 'true' }} run: echo "IS_PARENT_MODIFIED=true" >> $GITHUB_ENV - name: build and push run: "./.github/scripts/build-images.sh" env: IMG_TAG: "${{ matrix.tag }}" DF_PATH: "./commons/${{ github.job }}/${{ matrix.tag }}" DBX_PLATFORM: ${{ matrix.platform }} - id: set_is_parent_modified run: echo "is_parent_modified=${MODIFIED}" >> $GITHUB_OUTPUT data-analytics: runs-on: ubuntu-latest needs: hadoop env: DH_REPO: "cloudsuite/${{ github.job }}" strategy: matrix: tag: ["latest"] platform: ["linux/amd64,linux/arm64,linux/riscv64"] steps: - name: checkout uses: actions/checkout@v3 with: fetch-depth: 0 - if: ${{ needs.hadoop.outputs.is_parent_modified == 'true' }} run: echo "IS_PARENT_MODIFIED=true" >> $GITHUB_ENV - name: build and push run: "./.github/scripts/build-images.sh" env: IMG_TAG: "${{ matrix.tag }}" DF_PATH: "./benchmarks/${{ github.job }}/${{ matrix.tag }}" DBX_PLATFORM: ${{ matrix.platform }} data-caching: runs-on: ubuntu-latest needs: memcached env: DH_REPO: "cloudsuite/${{ github.job }}" strategy: matrix: include: - tag: "server" platform: "linux/amd64,linux/arm64,linux/riscv64" - tag: "client" platform: "linux/amd64,linux/arm64,linux/riscv64" steps: - name: checkout uses: actions/checkout@v3 with: fetch-depth: 0 - if: ${{ needs.memcached.outputs.is_parent_modified == 'true' }} run: echo "IS_PARENT_MODIFIED=true" >> $GITHUB_ENV - name: build and push run: "./.github/scripts/build-images.sh" env: IMG_TAG: "${{ matrix.tag }}" DF_PATH: "./benchmarks/${{ github.job }}/${{ matrix.tag }}" DBX_PLATFORM: ${{ matrix.platform }} data-serving: runs-on: ubuntu-latest needs: cassandra env: DH_REPO: "cloudsuite/${{ github.job }}" strategy: matrix: tag: ["server", "client"] platform: ["linux/amd64,linux/arm64,linux/riscv64"] steps: - name: checkout uses: actions/checkout@v3 with: fetch-depth: 0 - if: ${{ needs.cassandra.outputs.is_parent_modified == 'true' }} run: echo "IS_PARENT_MODIFIED=true" >> $GITHUB_ENV - name: build and push run: "./.github/scripts/build-images.sh" env: IMG_TAG: "${{ matrix.tag }}" DF_PATH: "./benchmarks/${{ github.job }}/${{ matrix.tag }}" DBX_PLATFORM: ${{ matrix.platform }} data-serving-relational: runs-on: ubuntu-latest needs: postgresql env: DH_REPO: "cloudsuite/${{ github.job }}" strategy: matrix: tag: ["server", "client"] platform: ["linux/amd64,linux/arm64"] steps: - name: checkout uses: actions/checkout@v3 with: fetch-depth: 0 - if: ${{ needs.cassandra.outputs.is_parent_modified == 'true' }} run: echo "IS_PARENT_MODIFIED=true" >> $GITHUB_ENV - name: build and push run: "./.github/scripts/build-images.sh" env: IMG_TAG: "${{ matrix.tag }}" DF_PATH: "./benchmarks/${{ github.job }}/${{ matrix.tag }}" DBX_PLATFORM: ${{ matrix.platform }} graph-analytics: runs-on: ubuntu-latest needs: spark env: DH_REPO: "cloudsuite/${{ github.job }}" strategy: matrix: tag: ["latest"] platform: ["linux/amd64,linux/arm64,linux/riscv64"] steps: - name: checkout uses: actions/checkout@v3 with: fetch-depth: 0 - if: ${{ needs.spark.outputs.is_parent_modified == 'true' }} run: echo "IS_PARENT_MODIFIED=true" >> $GITHUB_ENV - name: build and push run: "./.github/scripts/build-images.sh" env: IMG_TAG: "${{ matrix.tag }}" DF_PATH: "./benchmarks/${{ github.job }}/${{ matrix.tag }}" DBX_PLATFORM: ${{ matrix.platform }} in-memory-analytics: runs-on: ubuntu-latest needs: spark env: DH_REPO: "cloudsuite/${{ github.job }}" strategy: matrix: tag: ["latest"] platform: ["linux/amd64,linux/arm64,linux/riscv64"] steps: - name: checkout uses: actions/checkout@v3 with: fetch-depth: 0 - if: ${{ needs.spark.outputs.is_parent_modified == 'true' }} run: echo "IS_PARENT_MODIFIED=true" >> $GITHUB_ENV - name: build and push run: "./.github/scripts/build-images.sh" env: IMG_TAG: "${{ matrix.tag }}" DF_PATH: "./benchmarks/${{ github.job }}/${{ matrix.tag }}" DBX_PLATFORM: ${{ matrix.platform }} media-streaming: runs-on: ubuntu-latest needs: base-os env: DH_REPO: "cloudsuite/${{ github.job }}" strategy: matrix: tag: ["client", "server", "dataset"] platform: ["linux/amd64,linux/arm64,linux/riscv64"] steps: - name: checkout uses: actions/checkout@v3 with: fetch-depth: 0 - if: ${{ needs.base-os.outputs.is_parent_modified == 'true' }} run: echo "IS_PARENT_MODIFIED=true" >> $GITHUB_ENV - name: build and push run: "./.github/scripts/build-images.sh" env: IMG_TAG: "${{ matrix.tag }}" DF_PATH: "./benchmarks/${{ github.job }}/${{ matrix.tag }}" DBX_PLATFORM: ${{ matrix.platform }} web-search: runs-on: ubuntu-latest needs: faban env: DH_REPO: "cloudsuite/${{ github.job }}" strategy: matrix: tag: ["client", "server", "dataset"] platform: ["linux/amd64,linux/arm64"] steps: - name: checkout uses: actions/checkout@v3 with: fetch-depth: 0 - if: ${{ needs.faban.outputs.is_parent_modified == 'true' }} run: echo "IS_PARENT_MODIFIED=true" >> $GITHUB_ENV - name: build and push run: "./.github/scripts/build-images.sh" env: IMG_TAG: "${{ matrix.tag }}" DF_PATH: "./benchmarks/${{ github.job }}/${{ matrix.tag }}" DBX_PLATFORM: ${{ matrix.platform }} web-serving: runs-on: ubuntu-latest needs: [faban, mysql, memcached] env: DH_REPO: "cloudsuite/${{ github.job }}" strategy: matrix: tag: ["db_server", "faban_client", "memcached_server", "web_server"] platform: ["linux/amd64,linux/arm64,linux/riscv64"] steps: - name: checkout uses: actions/checkout@v3 with: fetch-depth: 0 - if: ${{ needs.faban.outputs.is_parent_modified == 'true' || needs.mysql.outputs.is_parent_modified == 'true' || needs.memcached.outputs.is_parent_modified == 'true' }} run: echo "IS_PARENT_MODIFIED=true" >> $GITHUB_ENV - name: build and push run: "./.github/scripts/build-images.sh" env: IMG_TAG: "${{ matrix.tag }}" DF_PATH: "./benchmarks/${{ github.job }}/${{ matrix.tag }}" DBX_PLATFORM: ${{ matrix.platform }} movielens-dataset: runs-on: ubuntu-latest needs: base-os env: DH_REPO: "cloudsuite/${{ github.job }}" strategy: matrix: tag: ["latest"] platform: ["linux/amd64,linux/arm64,linux/riscv64"] steps: - name: checkout uses: actions/checkout@v3 with: fetch-depth: 0 - if: ${{ needs.base-os.outputs.is_parent_modified == 'true' }} run: echo "IS_PARENT_MODIFIED=true" >> $GITHUB_ENV - name: build and push run: "./.github/scripts/build-images.sh" env: IMG_TAG: "${{ matrix.tag }}" DF_PATH: "./datasets/${{ github.job }}/${{ matrix.tag }}" DBX_PLATFORM: ${{ matrix.platform }} twitter-dataset-graph: runs-on: ubuntu-latest needs: base-os env: DH_REPO: "cloudsuite/${{ github.job }}" strategy: matrix: tag: ["latest"] platform: ["linux/amd64,linux/arm64,linux/riscv64"] steps: - name: checkout uses: actions/checkout@v3 with: fetch-depth: 0 - if: ${{ needs.base-os.outputs.is_parent_modified == 'true' }} run: echo "IS_PARENT_MODIFIED=true" >> $GITHUB_ENV - name: build and push run: "./.github/scripts/build-images.sh" env: IMG_TAG: "${{ matrix.tag }}" DF_PATH: "./datasets/${{ github.job }}/${{ matrix.tag }}" DBX_PLATFORM: ${{ matrix.platform }} wikimedia-pages-dataset: runs-on: ubuntu-latest needs: base-os env: DH_REPO: "cloudsuite/${{ github.job }}" strategy: matrix: tag: ["latest"] platform: ["linux/amd64,linux/arm64,linux/riscv64"] steps: - name: checkout uses: actions/checkout@v3 with: fetch-depth: 0 - if: ${{ needs.base-os.outputs.is_parent_modified == 'true' }} run: echo "IS_PARENT_MODIFIED=true" >> $GITHUB_ENV - name: build and push run: "./.github/scripts/build-images.sh" env: IMG_TAG: "${{ matrix.tag }}" DF_PATH: "./datasets/${{ github.job }}/${{ matrix.tag }}" DBX_PLATFORM: ${{ matrix.platform }} ================================================ FILE: .github/workflows/spell-check.yaml ================================================ on: push: branches: - main - dev pull_request: branches: - main - dev jobs: spell-check: runs-on: ubuntu-latest steps: - name: checkout uses: actions/checkout@v2 with: fetch-depth: 0 - name: spell-check uses: rojopolis/spellcheck-github-actions@0.29.0 ================================================ FILE: .gitignore ================================================ .DS_Store ================================================ FILE: .spellcheck.yml ================================================ matrix: - name: md source aspell: lang: en d: en_US ignore-case: true mode: html default_encoding: utf-8 dictionary: wordlists: - "./.wordlist.txt" pipeline: - pyspelling.filters.markdown: - pyspelling.filters.html: comments: false ignores: [code, pre, href] - pyspelling.filters.text: sources: - docs/*.md - docs/**/*.md ================================================ FILE: .wordlist.txt ================================================ ALS analytical analytics backend balancer basedocker benchmarked benchmarking BuildKit buildkitd buildx cassandra cd CLI clientdocker cloudsuite CloudSuite Cloudsuite's cmd conf cpufreq cpus cpuset csv datacenters dataset datasets dhpulls dhrepo dhstars dns Dockerfile Dockerfiles dockerhub DockerHub dP dt Elgg entrypoint epfl ethernet faban FastCGI fb filesystem fpm frontend Gbit GBs GC github GraphX grouplens hadoop HDFS HHVM HipHop hostname hostnames httperf https IP IPAddress JVM JIT keyspace LLC localhost login MapReduce masterdocker Mbps md Mediawiki memcache memcached MemcacheServer memcacheserverdocker metadata middleware microarchitectures MLlib Moby Movielens Multisocket multuarch myratings MySQL MysqlServer mysqlserverdocker mysqlserverdocker nginx NoSQL Nutch OLTP OPERATIONCOUNT os PageRank parallelize parallelized parsa php PHP pingable pregenerated qemu QEMU QoS README realtime Recommender RECORDCOUNT repo runtime scalability Skylake slavedocker solr solr's SQL src stddev sudo sys sysbench taskset TCP TPC tpcc threadcount txt UI usertable usr uwsgi vectorization videoperf VM VMs warmup WebServer webserverdocker webserverdocker Wikimedia yaml YCSB pre latencies TLS Elgg's ================================================ FILE: LICENSE.md ================================================ CloudSuite consists of several software components that are governed by various licensing terms, in addition to software that was developed internally. Anyone interested in using CloudSuite needs to fully understand and abide by the licenses governing all the software components. ### Software developed externally (not by the CloudSuite group) * [Nginx Web Server](http://nginx.org/LICENSE) * [PHP](http://www.php.net/license/3_01.txt) * [APC (Alternative PHP Cache)](http://www.php.net/license/3_01.txt) * [Nutch](http://www.apache.org/licenses/LICENSE-2.0) * [Hadoop](http://www.apache.org/licenses/LICENSE-2.0) * [Mahout](http://www.apache.org/licenses/LICENSE-2.0) * [Cassandra](http://www.apache.org/licenses/LICENSE-2.0) * [Yahoo! Cloud Serving Benchmark Framework](https://github.com/brianfrankcooper/YCSB/blob/master/LICENSE.txt) * [Faban workload generator](http://www.opensource.org/licenses/cddl1.php) * [Memcached](https://github.com/memcached/memcached/blob/master/LICENSE) * [Httperf](https://github.com/httperf/httperf/blob/master/COPYRIGHT) * [Spark](https://github.com/apache/spark/blob/master/LICENSE) * [MLlib](https://github.com/apache/spark/blob/master/LICENSE) * [GraphX](https://github.com/apache/spark/blob/master/LICENSE) * [Sorl](http://www.apache.org/licenses/LICENSE-2.0) * [Zookeeper](http://www.apache.org/licenses/LICENSE-2.0) * [Lucene](http://www.apache.org/licenses/LICENSE-2.0) * [Ant](http://www.apache.org/licenses/LICENSE-2.0) * [Elgg](https://www.gnu.org/licenses/gpl-2.0.html) ### Software developed internally (by the CloudSuite group) **CloudSuite 4.0 License** CloudSuite 4.0 Benchmark Suite Copyright © 2011-2023, Parallel Systems Architecture Lab, EPFL All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Parallel Systems Architecture Laboratory, EPFL, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PARALLEL SYSTEMS ARCHITECTURE LABORATORY, EPFL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: README.md ================================================ # CloudSuite 4.0 # **This branch contains the release of CloudSuite v4.0. If you are looking for CloudSuite 3, please checkout the [CSv3][CSv3] branch.** [CloudSuite][csp] is a benchmark suite for cloud services. The fourth release consists of eight first-party applications that have been selected based on their popularity in today's datacenters. The benchmarks are based on real-world software stacks and represent real-world setups. CloudSuite 4.0 includes a thorough software stack update and bug fixes for all workloads. It also includes support for all workloads on ARM to follow the rising trend of the ARM server market. It also features detailed guidelines for tuning and running the workloads in representative states, facilitating ease of use. # How to Run # For more details on how to run the workloads, please follow each workload's documentation: - [Data Analytics](docs/benchmarks/data-analytics.md) - [Data Caching](docs/benchmarks/data-caching.md) - [Data Serving](docs/benchmarks/data-serving.md) - [Graph Analytics](docs/benchmarks/graph-analytics.md) - [In-memory Analytics](docs/benchmarks/in-memory-analytics.md) - [Media Streaming](docs/benchmarks/media-streaming.md) - [Web Search](docs/benchmarks/web-search.md) - [Web Serving](docs/benchmarks/web-serving.md) To ease the deployment of CloudSuite into private and public cloud systems, we provide docker images for all CloudSuite benchmarks (available [here][csb]). # Workload Status # To see which workloads are currently functioning on the new architectures, you can find the status matrix [here][status_pg]. # Licensing # CloudSuite's software components are all available as open-source software. All of the software components are governed by their own licensing terms. Researchers interested in using CloudSuite are required to fully understand and abide by the licensing terms of the various components. For more information, please refer to the [license page][csl]. # Support # We encourage CloudSuite users to use GitHub issues to request for enhancements, questions or bug fixes. [csp]: http://cloudsuite.ch "CloudSuite Page" [csl]: http://cloudsuite.ch/pages/license/ "CloudSuite License" [csb]: http://cloudsuite.ch/#download "CloudSuite Benchmarks" [CSv3]: https://github.com/parsa-epfl/cloudsuite/tree/CSv3 "CloudSuite v3" [status_pg]: https://github.com/parsa-epfl/cloudsuite/wiki/CloudSuite-4.0-Workload-Status-Matrix ================================================ FILE: benchmarks/data-analytics/latest/Dockerfile ================================================ FROM cloudsuite/hadoop:2.10.2 ENV MAHOUT_VERSION 14.1 ENV MAHOUT_HOME /opt/mahout-${MAHOUT_VERSION} RUN mkdir ${MAHOUT_HOME} /user # Install Mahout RUN set -x \ && URL=https://downloads.apache.org/mahout/${MAHOUT_VERSION}/apache-mahout-distribution-${MAHOUT_VERSION}.tar.gz \ && curl ${URL} | tar -xzC ${MAHOUT_HOME} COPY files/benchmark.sh /root/ COPY files/docker-entrypoint.py /root/ COPY files/mahout-examples-0.13.0-job.jar ${MAHOUT_HOME}/. COPY files/categories /user/ RUN chmod +x /root/benchmark.sh /root/docker-entrypoint.py \ && ln -s /root/benchmark.sh /bin/benchmark ENTRYPOINT ["/root/docker-entrypoint.py"] ================================================ FILE: benchmarks/data-analytics/latest/files/benchmark.sh ================================================ #!/bin/bash RED='\033[0;31m' RESET='\033[0m' source ~/.bashrc echo -e "Mahout: Start HDFS server" ${HADOOP_HOME}/bin/hdfs dfs -test -e /data/wiki if [ $? -ne 0 ]; then echo -e "Mahout: make dir for /user/data/wiki" ${HADOOP_HOME}/bin/hdfs dfs -mkdir -p /user/data ${HADOOP_HOME}/bin/hdfs dfs -put /data/wiki /user/data/ fi START=$(($(date +"%s%N")/1000000)) # Create sequence files from wiki echo -e "${RED}Mahout: seqwiki${RESET}" ${MAHOUT_HOME}/bin/mahout seqwiki -c /user/categories -i /user/data/wiki -o /user/data/wiki-seq # Convert sequence files to vectors using bigrams echo -e "${RED}Mahout: seq2sparse${RESET}" ${MAHOUT_HOME}/bin/mahout seq2sparse -i /user/data/wiki-seq -o /user/data/wiki-vectors -lnorm -nv -wt tfidf -ow -ng 2 # Create training and holdout sets with a random 80-20 split of the generated vector dataset echo -e "${RED}Mahout: split${RESET}" ${MAHOUT_HOME}/bin/mahout split -i /user/data/wiki-vectors/tfidf-vectors --trainingOutput /user/data/training \ --testOutput /user/data/testing -rp 20 -ow -seq -xm sequential # Train Bayes model echo -e "${RED}Mahout: trainnb${RESET}" ${MAHOUT_HOME}/bin/mahout trainnb -i /user/data/training -o /user/data/model -li /user/data/labelindex -ow -c # Test on holdout set echo -e "${RED}Mahout: testnb${RESET}" ${MAHOUT_HOME}/bin/mahout testnb -i /user/data/testing -m /user/data/model -l /user/data/labelindex -ow -o /user/data/output -seq END=$(($(date +"%s%N")/1000000)) TIME=$(($END - $START)) echo -e "\nBenchmark time: ${TIME}ms" ================================================ FILE: benchmarks/data-analytics/latest/files/categories ================================================ Art Culture Economics Education Event Health History Industry Sports Geography Cities Countries Language Law Media Nature People Philosophy Politics Regions Religion Science Society Technology Transport ================================================ FILE: benchmarks/data-analytics/latest/files/docker-entrypoint.py ================================================ #!/usr/bin/env python3 import os import sys import subprocess import argparse args = sys.argv[1:] parser = argparse.ArgumentParser() parser.add_argument("--yarn-cores", help="YARN: number of cores for yarn", default=8) parser.add_argument("--mapreduce-mem", help="MAP_REDUCE: memory per mapreduce worker", default=2096) args_parsed, unknown = parser.parse_known_args() yarn_max_mem = int(args_parsed.mapreduce_mem) * int(args_parsed.yarn_cores) args.append("--yarn-mem=" + str(yarn_max_mem + 812)) print(str(args)) subprocess.call(['./hadoop-start.py'] + args) ================================================ FILE: benchmarks/data-analytics/latest/files/mahout-examples-0.13.0-job.jar ================================================ [File too large to display: 76.8 MB] ================================================ FILE: benchmarks/data-caching/client/Dockerfile ================================================ FROM cloudsuite/base-os:ubuntu # add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added RUN groupadd -r memcache && useradd -r -g memcache memcache ENV DEBIAN_FRONTEND noninteractive RUN buildDeps='curl gcc libc6-dev make' \ && set -x \ && apt-get update && apt-get install -y $buildDeps libevent-dev vim --no-install-recommends \ && rm -rf /var/lib/apt/lists/* \ && curl -k -L --remote-name http://github.com/parsa-epfl/memcached-loadtester/archive/refs/tags/v4.0.tar.gz \ && mkdir -p /usr/src/memcached \ && tar xvf v4.0.tar.gz -C /usr/src/memcached --strip-components=1 \ && rm v4.0.tar.gz \ && cd /usr/src/memcached/memcached_client \ && make -j $(nproc) \ && chown -R memcache:memcache /usr/src/memcached \ && apt-get purge -y --auto-remove $buildDeps COPY docker-entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"] USER memcache CMD ["/bin/bash"] ================================================ FILE: benchmarks/data-caching/client/docker-entrypoint.sh ================================================ #!/bin/bash ARGS=() MODE="bash" SCALE=30 WORKERS=4 SERVER_MEMORY=4096 INTERVAL=1 GET_RATIO=0.8 CONNECTION=200 RPS=10000 NEGATIVE_EXPONENTIAL=false while (( ${#@} )); do case ${1} in --m=*) MODE=${1#*=} ;; --S=*) SCALE=${1#*=} ;; --w=*) WORKERS=${1#*=} ;; --D=*) SERVER_MEMORY=${1#*=} ;; --T=*) INTERVAL=${1#*=} ;; --g=*) GET_RATIO=${1#*=} ;; --c=*) CONNECTION=${1#*=} ;; --r=*) RPS=${1#*=} ;; --ne) NEGATIVE_EXPONENTIAL=true ;; *) ARGS+=(${1}) ;; esac shift done set -- ${ARGS[@]} if [ "$MODE" = 'S&W' ]; then echo "scale and warmup" /usr/src/memcached/memcached_client/loader \ -a /usr/src/memcached/twitter_dataset/twitter_dataset_unscaled \ -o /usr/src/memcached/twitter_dataset/twitter_dataset_${SCALE}x \ -s /usr/src/memcached/memcached_client/docker_servers/docker_servers.txt \ -w ${WORKERS} -S ${SCALE} -D ${SERVER_MEMORY} -j -T ${INTERVAL} elif [ "$MODE" = 'W' ]; then echo "warmup" /usr/src/memcached/memcached_client/loader \ -a /usr/src/memcached/twitter_dataset/twitter_dataset_${SCALE}x \ -s /usr/src/memcached/memcached_client/docker_servers/docker_servers.txt \ -w ${WORKERS} -S 1 -D ${SERVER_MEMORY} -j -T ${INTERVAL} elif [ "$MODE" = 'TH' ]; then echo "max throughput" /usr/src/memcached/memcached_client/loader \ -a /usr/src/memcached/twitter_dataset/twitter_dataset_${SCALE}x \ -s /usr/src/memcached/memcached_client/docker_servers/docker_servers.txt \ -g ${GET_RATIO} -w ${WORKERS} -c ${CONNECTION} -T ${INTERVAL} elif [ "$MODE" = 'RPS' ]; then echo "RPS" if [ "$NEGATIVE_EXPONENTIAL" = true ]; then ADDITIONA_OPTION="-e" fi /usr/src/memcached/memcached_client/loader \ -a /usr/src/memcached/twitter_dataset/twitter_dataset_${SCALE}x \ -s /usr/src/memcached/memcached_client/docker_servers/docker_servers.txt \ -g ${GET_RATIO} -w ${WORKERS} -c ${CONNECTION} -T ${INTERVAL} $ADDITIONA_OPTION -r ${RPS} elif [ "$MODE" = "bash" ]; then # bash exec /bin/bash fi ================================================ FILE: benchmarks/data-caching/server/Dockerfile ================================================ FROM cloudsuite/memcached:1.6.15 # the entry point is set to memcached in the base image CMD ["-t", "2", "-m", "2048", "-n", "550"] ================================================ FILE: benchmarks/data-serving/.gitignore ================================================ *~ ================================================ FILE: benchmarks/data-serving/client/Dockerfile ================================================ FROM cloudsuite/cassandra:4.1.0 ENV YCSB_VERSION 0.17.0 RUN wget -q --show-progress --progress=bar:force https://github.com/brianfrankcooper/YCSB/releases/download/$YCSB_VERSION/ycsb-$YCSB_VERSION.tar.gz -O /ycsb-$YCSB_VERSION.tar.gz \ && tar -xzf /ycsb-$YCSB_VERSION.tar.gz && rm /ycsb-$YCSB_VERSION.tar.gz && mv /ycsb-$YCSB_VERSION /ycsb COPY setup_tables.txt /setup_tables.txt COPY warmup.sh /warmup.sh COPY load.sh /load.sh RUN chmod +x /load.sh /warmup.sh ================================================ FILE: benchmarks/data-serving/client/load.sh ================================================ #!/bin/bash # Usage: load.sh if [ $# -le 2 ]; then echo "usage: load.sh " exit 0 fi if [ -z $4 ]; then THREADS=1 else THREADS=$4 fi if [ -z $5 ]; then let OP_COUNT="60*$3" else OP_COUNT=$5 fi echo '======================================================' echo "server IP: $1" echo "Database record count: $2" echo "Target load: $3 rps" echo "Loader threads count: $THREADS" echo "Opeartion count: $OP_COUNT" echo "Make sure you have run the warmup.sh before loading the server, and use the same record count here." echo '======================================================' /ycsb/bin/ycsb.sh run cassandra-cql -p hosts=$1 -P /ycsb/workloads/workloada \ -p recordcount=$2 -p operationcount=$OP_COUNT \ -threads $THREADS -target $3 -s ================================================ FILE: benchmarks/data-serving/client/setup_tables.txt ================================================ create keyspace if not exists ycsb WITH REPLICATION = {'class' : 'SimpleStrategy', 'replication_factor': 3 }; use ycsb; create table if not exists usertable ( y_id varchar primary key, field0 varchar, field1 varchar, field2 varchar, field3 varchar, field4 varchar, field5 varchar, field6 varchar, field7 varchar, field8 varchar, field9 varchar); exit; ================================================ FILE: benchmarks/data-serving/client/warmup.sh ================================================ #!/bin/bash # This script helps to fill the server database with given data set size. # Usage: warmup.sh # Each record takes 1KB to store, so if you want a 10GB database, just giving 10M records. if [ $# -le 1 ]; then echo "usage: warm.sh " exit 0 fi if [ -z $3 ]; then THREADS=1 else THREADS=$3 fi echo '======================================================' echo "server IP: $1" echo "Fill the database with $2 records" echo "Load generator threads count: $THREADS" echo '======================================================' echo '======================================================' echo 'Creating a usertable for the seed server' echo '======================================================' first_server=$(cut -d',' -f1 <<< "$1") exit=0 while [ $exit -eq 0 ]; do set +e cqlsh -f /setup_tables.txt $first_server if [[ "$?" -eq 0 ]]; then exit=1 else echo 'Cannot connect to the seed server. Trying again...' fi set -e sleep 5 done echo '======================================================' echo 'Populate the database' echo '======================================================' /ycsb/bin/ycsb.sh load cassandra-cql -p hosts=$1 -P /ycsb/workloads/workloada -p recordcount=$2 -s -threads $THREADS echo '======================================================' echo 'Warm up is done.' echo '======================================================' ================================================ FILE: benchmarks/data-serving/server/Dockerfile ================================================ FROM cloudsuite/cassandra:4.1.0 RUN apt update && apt install -y --no-install-recommends python3-yaml && rm -rf /var/lib/apt/lists/* COPY docker-entrypoint.py / ENTRYPOINT ["/docker-entrypoint.py"] EXPOSE 7000 7001 7199 9042 9160 ================================================ FILE: benchmarks/data-serving/server/README.md ================================================ # Cassandra Server # ## Single Node Check the configuration parameters: conf/cassandra.yaml contains default values for the Cassandra parameters. First, ensure that the paths for the following parameters point to the directories where you have write permission. ``` data_file_directories, commitlog_directory, and saved_caches_directory ``` Run the test command listed below, if there are no errors, then your installation was likely successful. ``` cassandra -f ``` ## Multi Node You need to configure each Cassandra instance properly to communicate with each other. The way that a Cassandra node is designed to communicate with other nodes is through the Gossip protocol. Each Cassandra node should know at least one reliable Cassandra node called the seed. You can find more details at this website: http://wiki.apache.org/cassandra/GettingStarted. i. Configure the seed for each node in the conf/cassandra.yaml file. ii. Configure the listen_address and rpc_address in conf/cassandra.yaml to the hostname (or IP of the node). ================================================ FILE: benchmarks/data-serving/server/docker-entrypoint.py ================================================ #!/usr/bin/env python3 import socket def get_ip(): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.settimeout(0) try: # doesn't even have to be reachable s.connect(('8.8.8.8', 1)) IP = s.getsockname()[0] except Exception: IP = '127.0.0.1' finally: s.close() return IP import argparse parser = argparse.ArgumentParser() parser.add_argument("--listen-ip", "-a", help="The listening IP address of Cassandra. If no value provided, the script tries to find the primary IP address by itself.", default=get_ip()) parser.add_argument("--reader-count", "-r", type=int, help="The number of reader threads. Recommended value: 16 per disk to store data. Default is 16", default=16) parser.add_argument("--writer-count", "-w", type=int, help="The number of writer threads. Recommended value: 8 per CPU core. Default is 32.", default=32) parser.add_argument("--heap-size", type=int, help="The size of JVM heap in GB. Default is max(min(1/2 ram, 1GB), min(1/4 ram, 8GB)).") parser.add_argument("--seed-server-ip", help="The IP address of the seed server. This option is only for multiple-node deployment.") parser.add_argument("--affinity", help="The CPU ids (separated by comma) given to Cassandra to set JVM affinity. By default, Cassandra would use all CPU cores.") args = parser.parse_args() import yaml import os import os.path as path import shutil CASSANDRA_CONFIG = os.environ["CASSANDRA_CONFIG"] # Backup the original file if not path.exists(f"{CASSANDRA_CONFIG}/cassandra.yaml.bak"): shutil.copy(f"{CASSANDRA_CONFIG}/cassandra.yaml", f"{CASSANDRA_CONFIG}/cassandra.yaml.bak") if not path.exists(f"{CASSANDRA_CONFIG}/jvm-server.options.bak"): shutil.copy(f"{CASSANDRA_CONFIG}/jvm-server.options", f"{CASSANDRA_CONFIG}/jvm-server.options.bak") # Now, modify the cassandra.yaml with open(f"{CASSANDRA_CONFIG}/cassandra.yaml") as f: config = yaml.safe_load(f) # Update some terms accordingly. config["rpc_address"] = "0.0.0.0" config["listen_address"] = args.listen_ip config["broadcast_address"] = args.listen_ip config["broadcast_rpc_address"] = args.listen_ip config["seed_provider"][0]["parameters"][0]["seeds"] = f"{args.listen_ip}:7000" config["concurrent_reads"] = args.reader_count config["concurrent_counter_writes"] = args.reader_count config["concurrent_writes"] = args.writer_count if args.seed_server_ip: config["seed_provider"][0]["parameters"][0]["seeds"] = f"{args.seed_server_ip}:7000" print(f"A regular server is listened on {args.listen_ip} and will search for seed at {args.seed_server_ip}.") else: print(f"A seed server is listened on {args.listen_ip}") # Dump the file with open(f"{CASSANDRA_CONFIG}/cassandra.yaml", "w") as f: yaml.safe_dump(config, f) # Then, process the jvm.options with open(f"{CASSANDRA_CONFIG}/jvm-server.options") as f: jvm_options = f.readlines() if args.heap_size: # Clean any old settings for idx, l in enumerate(jvm_options): if l.startswith("-Xms"): jvm_options[idx] = "" if l.startswith("-Xmx"): jvm_options[idx] = "" # Add heap size jvm_options.append(f"-Xms{args.heap_size}G\n") jvm_options.append(f"-Xmx{args.heap_size}G\n") if args.affinity: found = False for idx, l in enumerate(jvm_options): if l.startswith("-Dcassandra.available_processors"): jvm_options[idx] = f"-Dcassandra.available_processors={args.affinity}\n" found = True if not found: jvm_options.append("-Dcassandra.available_processors={args.affinity}\n") # Write it back with open(f"{CASSANDRA_CONFIG}/jvm-server.options", "w") as f: f.writelines(jvm_options) os.execvp("cassandra", ["cassandra", "-R", "-f"]) ================================================ FILE: benchmarks/data-serving-relational/client/Dockerfile ================================================ FROM cloudsuite/base-os:ubuntu ENV DEBIAN_FRONTEND noninteractive # 1. install necessary software (sysbench) RUN apt update && apt install git sysbench python3 -y # 2. clone sysbench-tpcc's repo and install its script RUN git clone https://github.com/Percona-Lab/sysbench-tpcc && cp sysbench-tpcc/*.lua /usr/share/sysbench/ # 3. Copy the template load file COPY ./docker-entrypoint.py /root COPY ./template/tpcc.py /root/template/tpcc.py COPY ./template/oltp-rw.py /root/template/oltp-rw.py COPY ./template/database.conf /root/template/database.conf ENV DATABASE_CONF_FILE /root/template/database.conf RUN chmod +x /root/docker-entrypoint.py RUN chmod +x /root/template/tpcc.py RUN chmod +x /root/template/oltp-rw.py ENTRYPOINT ["/root/docker-entrypoint.py"] ================================================ FILE: benchmarks/data-serving-relational/client/docker-entrypoint.py ================================================ #!/usr/bin/env python3 import os import sys import subprocess import argparse args = sys.argv[1:] parser = argparse.ArgumentParser() parser.add_argument("--tpcc", help="Run TPC-C benchmark", action='store_true') parser.add_argument("--oltp-rw", help="Run sysbench OLTP Read/Write workload", action='store_true') parser.add_argument("--server-ip", help="IP of the server to load") args_parsed, unknown = parser.parse_known_args() if not args_parsed.server_ip: print("Please pass the server IP as an argument with --server-ip=") sys.exit() print("args: " + str(args)) if not args_parsed.tpcc and not args_parsed.oltp_rw: print("Precise whenever it's --tpcc or --oltp-rw") sys.exit() import os import os.path as path import shutil def get_dict(lines): config_dict = {} for line in lines: is_enabled = True if "=" in line: if line.startswith("#"): is_enabled = False line = line[1:] # Remove `#` key, value = line.split("=", 1) key = key.strip() value = value.strip() config_dict[key] = (value, is_enabled) return config_dict def save_dict(config_dict, lines): # Reconstruct the updated configuration new_lines = [] for line in lines: if "=" in line: if line.startswith("#"): line = line[1:] key, _ = line.split("=", 1) key = key.strip() if config_dict[key][1]: new_lines.append(f"{key}={config_dict[key][0]}") else: new_lines.append(f"#{key}={config_dict[key][0]}") else: new_lines.append(line) new_config = "\n".join(new_lines) return new_config DATABASE_CONF_FILE = os.environ["DATABASE_CONF_FILE"] if not path.exists(f"{DATABASE_CONF_FILE}"): shutil.copy(f"{DATABASE_CONF_FILE}", f"{DATABASE_CONF_FILE}.bak") with open(f"{DATABASE_CONF_FILE}", "r") as f: lines = f.readlines() config_dict = get_dict(lines) # Update the desired key with the new value config_dict["pgsql-host"] = (args_parsed.server_ip, True) file_txt = save_dict(config_dict, lines) # Write it back with open(f"{DATABASE_CONF_FILE}", "w") as f: f.writelines(file_txt) if args_parsed.tpcc: subprocess.call(['/root/template/tpcc.py'] + args) else: subprocess.call(['/root/template/oltp-rw.py'] + args) ================================================ FILE: benchmarks/data-serving-relational/client/template/database.conf ================================================ db-driver=pgsql pgsql-host=128.178.116.117 pgsql-port=5432 pgsql-user=cloudsuite pgsql-password=cloudsuite pgsql-db=sbtest ================================================ FILE: benchmarks/data-serving-relational/client/template/oltp-rw.py ================================================ #!/usr/bin/env python3 import os import sys import subprocess import argparse # According to the code, the table structure is like the following: # - id: 4B (primary key) # - key: 4B # - c: 120B # - pad: 60B # As a result, each row takes 188B. # You can increase the dataset size by adding more parser = argparse.ArgumentParser() parser.add_argument("--run", help="Run the benchmark, must be warmuped up before with --warmup", action='store_true') parser.add_argument("--warmup", help="Warmup the benchmark, then can be ran with --run", action='store_true') parser.add_argument("--threads", "-t", help="Number of threads for the client", default=8, type=int) parser.add_argument("--report-interval", "-ri", help="Report interval for metrics in seconds", default=10, type=int) parser.add_argument("--record-count", "-c", help="Record count per table. Each record is 188B", default=1000000, type=int) parser.add_argument("--tables", "-n", help="Number of tables with `table_size` rows each", default=50, type=int) parser.add_argument("--rate", "-r", help="The expected load (transaction / sec)", type=int) parser.add_argument("--time", "-s", help="Length of the benchmark in seconds", default=360, type=int) args_parsed, unknown = parser.parse_known_args() # Warmup if not args_parsed.warmup and not args_parsed.run: print("Need to pass at least --run or --warmup argument") exit() if args_parsed.warmup: os.system(f"sysbench oltp_read_write --config-file=/root/template/database.conf --threads={args_parsed.threads} --time={args_parsed.time} --report-interval={args_parsed.report_interval} prepare --table_size={args_parsed.record_count} --tables={args_parsed.tables}") elif not args_parsed.rate: os.system(f"sysbench oltp_read_write --config-file=/root/template/database.conf --threads={args_parsed.threads} --time={args_parsed.time} --report-interval={args_parsed.report_interval} run --table_size={args_parsed.record_count} --tables={args_parsed.tables}") else: os.system(f"sysbench oltp_read_write --config-file=/root/template/database.conf --threads={args_parsed.threads} --time={args_parsed.time} --report-interval={args_parsed.report_interval} run --table_size={args_parsed.record_count} --tables={args_parsed.tables} --rate={args_parsed.rate}") ================================================ FILE: benchmarks/data-serving-relational/client/template/tpcc.py ================================================ #!/usr/bin/env python3 import os import sys import subprocess import argparse parser = argparse.ArgumentParser() parser.add_argument("--run", help="Run the benchmark, must be warmuped up before with --warmup", action='store_true') parser.add_argument("--warmup", help="Warmup the benchmark, then can be ran with --run", action='store_true') parser.add_argument("--threads", "-t", help="Number of threads for the client", default=8, type=int) parser.add_argument("--report-interval", "-ri", help="Report interval for metrics in seconds", default=10, type=int) parser.add_argument("--time", "-s", help="Length of the benchmark in seconds", default=360, type=int) parser.add_argument("--scale", "-n", help="Scale of the dataset", default=10, type=int) parser.add_argument("--rate", "-r", help="The expected load (transaction / sec)", type=int) args_parsed, unknown = parser.parse_known_args() # Warmup if not args_parsed.warmup and not args_parsed.run: print("Need to pass at least --run or --warmup argument") exit() if args_parsed.warmup: os.system(f"sysbench tpcc --config-file=/root/template/database.conf --threads={args_parsed.threads} prepare --scale={args_parsed.scale}") elif not args_parsed.rate: os.system(f"sysbench tpcc --config-file=/root/template/database.conf --threads={args_parsed.threads} --time={args_parsed.time} --report-interval={args_parsed.report_interval} run --scale={args_parsed.scale}") else: os.system(f"sysbench tpcc --config-file=/root/template/database.conf --threads={args_parsed.threads} --time={args_parsed.time} --report-interval={args_parsed.report_interval} run --scale={args_parsed.scale} --rate={args_parsed.rate}") ================================================ FILE: benchmarks/data-serving-relational/server/Dockerfile ================================================ FROM cloudsuite/postgresql:15 # Install sudo for user switching RUN apt update && apt install sudo python3 -y # Make the database access public RUN echo 'host\tall\tcloudsuite\t0.0.0.0/0\tscram-sha-256' >> /etc/postgresql/15/main/pg_hba.conf # Copy the entrypoint COPY ./docker-entrypoint.py /root RUN chmod +x /root/docker-entrypoint.py ENTRYPOINT ["/root/docker-entrypoint.py"] ================================================ FILE: benchmarks/data-serving-relational/server/docker-entrypoint.py ================================================ #!/usr/bin/env python3 import socket def get_ip(): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.settimeout(0) try: # doesn't even have to be reachable s.connect(('8.8.8.8', 1)) IP = s.getsockname()[0] except Exception: IP = '127.0.0.1' finally: s.close() return IP import argparse parser = argparse.ArgumentParser() # If no value provided, the script tries to find the primary IP address by itself. = get_ip() parser.add_argument("--listen-addresses", "-a", help="The listening IP address of PostGRES.", default="'*'") parser.add_argument("--number", "-n", type=int, help="The number is not used, place holder for new argument.", default=0) args, unknown = parser.parse_known_args() import os import os.path as path import shutil def get_dict(lines): config_dict = {} for line in lines: is_enabled = True if "=" in line: if line.startswith("#"): is_enabled = False line = line[1:] # Remove `#` key, value = line.split("=", 1) key = key.strip() value = value.strip() config_dict[key] = (value, is_enabled) return config_dict def save_dict(config_dict, lines): # Reconstruct the updated configuration new_lines = [] for line in lines: if "=" in line: if line.startswith("#"): line = line[1:] key, _ = line.split("=", 1) key = key.strip() if config_dict[key][1]: new_lines.append(f"{key} = {config_dict[key][0]}") else: new_lines.append(f"#{key} = {config_dict[key][0]}") else: new_lines.append(line) new_config = "\n".join(new_lines) return new_config POSTGRE_HOMEDIR = os.environ["POSTGRE_HOME"] # Backup the original file if not path.exists(f"{POSTGRE_HOMEDIR}/postgresql.conf"): shutil.copy(f"{POSTGRE_HOMEDIR}/postgresql.conf", f"{POSTGRE_HOMEDIR}/postgresql.conf.bak") with open(f"{POSTGRE_HOMEDIR}/postgresql.conf", "r") as f: lines = f.readlines() config_dict = get_dict(lines) # Update the desired key with the new value config_dict["listen_addresses"] = (args.listen_addresses, True) # sed -i "s/#listen_addresses = 'localhost'/listen_addresses = '*'/g" /etc/postgresql/15/main/postgresql.conf file_txt = save_dict(config_dict, lines) # Write it back with open(f"{POSTGRE_HOMEDIR}/postgresql.conf", "w") as f: f.writelines(file_txt) os.system("service postgresql start") os.system("sudo -u postgres psql -c \"CREATE USER cloudsuite WITH PASSWORD 'cloudsuite';\"") # Create the user called `cloudsuite` os.system("sudo -u postgres psql -c \"CREATE DATABASE sbtest;\"") # Create a table named sbtest os.system("sudo -u postgres psql -c \"GRANT ALL PRIVILEGES ON DATABASE sbtest TO cloudsuite\"") # Gave permission to this table os.system("sudo -u postgres psql sbtest -c \"GRANT ALL ON SCHEMA public TO cloudsuite;\"") os.system("sudo -u postgres psql") ================================================ FILE: benchmarks/graph-analytics/latest/Dockerfile ================================================ FROM --platform=linux/amd64 cloudsuite/spark:3.3.2 as build WORKDIR /root # Copy files COPY benchmark /root/benchmark ENV SCALA_VERSION 2.13 # Build the benchmark using sbt RUN set -ex \ && apt-get update \ && apt-get install apt-transport-https curl gnupg -y --no-install-recommends \ && echo "deb https://repo.scala-sbt.org/scalasbt/debian all main" | tee /etc/apt/sources.list.d/sbt.list \ && echo "deb https://repo.scala-sbt.org/scalasbt/debian /" | tee /etc/apt/sources.list.d/sbt_old.list \ && curl -sL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x2EE0EA64E40A89B84B2DF73499E82A75642AC823" | gpg --no-default-keyring --keyring gnupg-ring:/etc/apt/trusted.gpg.d/scalasbt-release.gpg --import \ && chmod 644 /etc/apt/trusted.gpg.d/scalasbt-release.gpg \ && apt-get update -y \ && apt-get install -y --no-install-recommends sbt \ && rm -rf /var/lib/apt/lists/* # build and save `.jar` RUN cd /root/benchmark \ && sbt package \ && mv /root/benchmark/target/scala-$SCALA_VERSION/*.jar /root/benchmark/run_benchmark.sh /root \ && apt-get purge -y --auto-remove sbt \ && rm -r /root/benchmark \ && rm -r /root/.sbt /root/.cache \ && chmod +x /root/entrypoint.sh FROM cloudsuite/spark:3.3.2 # copy data from the build container COPY --from=build /root/graph-analytics-2.0.jar /root COPY --from=build /root/run_benchmark.sh /root COPY files/entrypoint.sh /root/entrypoint.sh RUN chmod +x /root/entrypoint.sh /root/run_benchmark.sh ENV BENCHMARK_JAR /root/graph-analytics-2.0.jar # This input file comes from in `datasets/twitter-dataset-graph` ENV INPUT_FILE /data/edges.csv ENTRYPOINT ["/root/entrypoint.sh"] ================================================ FILE: benchmarks/graph-analytics/latest/benchmark/build.sbt ================================================ name := "Graph Analytics" version := "2.0" organization := "PARSA" scalaVersion := "2.13.10" artifactName := { (sv: ScalaVersion, module: ModuleID, artifact: Artifact) => artifact.name + "-" + module.revision + "." + artifact.extension } libraryDependencies ++= Seq( "org.apache.spark" %% "spark-core" % "3.3.2", "org.apache.spark" %% "spark-graphx" % "3.3.2" ) ================================================ FILE: benchmarks/graph-analytics/latest/benchmark/run_benchmark.sh ================================================ #!/usr/bin/env bash read -r -d '' USAGE << EOS Usage: graph-analytics [SPARK_OPTIONS] SPARK_OPTIONS are passed on to spark-submit. EOS if [ -n "$INPUT_FILE" ]; then ARG_FILENAME=-file="${INPUT_FILE}" fi if [ -n "$WORKLOAD_NAME" ]; then ARG_WORKLOAD=-app="${WORKLOAD_NAME}" fi if [ -n "$NUM_ITER" ]; then ARG_NITERS=-niter="${NUM_ITER}" fi BENCHMARK_JAR=/root/graph-analytics-2.0.jar echo "Executing with: $ARG_FILENAME $ARG_WORKLOAD $ARG_NITERS" echo " SPARK_OPTIONS:"$@"" exec ${SPARK_HOME}/bin/spark-submit --class GraphAnalytics "$@" \ ${BENCHMARK_JAR} $ARG_FILENAME $ARG_WORKLOAD $ARG_NITERS ================================================ FILE: benchmarks/graph-analytics/latest/benchmark/src/main/scala/GraphAnalytics.scala ================================================ import java.io.File import scala.io.Source /* Graph analytics */ import org.apache.spark._ import org.apache.spark.graphx._ // To make some of the examples work we will also need RDD import org.apache.spark.rdd.RDD object GraphAnalytics { def main(args: Array[String]) : Unit = { // val options: List[(String, String)] = List() val options = args.map { arg => arg.dropWhile(_ == '-').split('=') match { case Array(opt, v) => (opt -> v) case _ => throw new IllegalArgumentException("Invalid argument: " + arg) } } var app = "pr" var niter = 3 var edgesFilename = "EDGES_FILES" options.foreach { case ("app", v) => app = v case ("niter", v) => niter = v.toInt case ("file", v) => edgesFilename = v case (opt, _) => throw new IllegalArgumentException("Invalid option: " + opt) } val conf = new SparkConf().setAppName("Graph analytics") val sc = new SparkContext(conf) val graph = GraphLoader.edgeListFile(sc, edgesFilename) graph.cache() var startTime = System.currentTimeMillis() if (app == "pr") { println("Running PageRank") val totalPR = graph.staticPageRank(niter).vertices.map(_._2).sum() println(s"Total PageRank = $totalPR") } else if (app == "cc") { println("Running Connected Components") val numComponents = graph.connectedComponents().vertices.map(_._2).distinct().count() println(s"Number of components = $numComponents") } else if (app == "tc") { println("Running Triangle Counting") val triangleCnt = graph.triangleCount().vertices.map(_._2).distinct().count() println(s"Number of triangles = $triangleCnt") } val runTime = System.currentTimeMillis() - startTime println(s"Running time = $runTime") } } ================================================ FILE: benchmarks/graph-analytics/latest/files/entrypoint.sh ================================================ #!/usr/bin/env bash exec /root/run_benchmark.sh "$@" ================================================ FILE: benchmarks/in-memory-analytics/latest/Dockerfile ================================================ FROM --platform=linux/amd64 cloudsuite/spark:3.3.2 as build WORKDIR /root # Benchmark files COPY movielens-als /root/movielens-als COPY files /root/ ENV SCALA_VERSION 2.13 # Build the benchmark using sbt RUN set -ex \ && apt-get update \ && apt-get install apt-transport-https curl gnupg -y --no-install-recommends \ && echo "deb https://repo.scala-sbt.org/scalasbt/debian all main" | tee /etc/apt/sources.list.d/sbt.list \ && echo "deb https://repo.scala-sbt.org/scalasbt/debian /" | tee /etc/apt/sources.list.d/sbt_old.list \ && curl -sL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x2EE0EA64E40A89B84B2DF73499E82A75642AC823" | gpg --no-default-keyring --keyring gnupg-ring:/etc/apt/trusted.gpg.d/scalasbt-release.gpg --import \ && chmod 644 /etc/apt/trusted.gpg.d/scalasbt-release.gpg \ && apt-get update -y \ && apt-get install -y --no-install-recommends sbt \ && rm -rf /var/lib/apt/lists/* RUN cd /root/movielens-als \ && sbt package \ && mv /root/movielens-als/target/scala-${SCALA_VERSION}/*.jar /root/movielens-als/run_benchmark.sh /root \ && apt-get purge -y --auto-remove sbt \ && rm -r /root/movielens-als \ && rm -r /root/.sbt /root/.cache \ && chmod +x /root/entrypoint.sh FROM cloudsuite/spark:3.3.2 # copy the old file COPY --from=build /root/movielens-als-2.0.jar /root COPY --from=build /root/run_benchmark.sh /root COPY /files/entrypoint.sh /root/entrypoint.sh ENV BENCHMARK_JAR /root/movielens-als-2.0.jar ENTRYPOINT ["/root/entrypoint.sh"] ================================================ FILE: benchmarks/in-memory-analytics/latest/files/entrypoint.sh ================================================ #!/usr/bin/env bash exec /root/run_benchmark.sh "$@" ================================================ FILE: benchmarks/in-memory-analytics/latest/files/spark-defaults.conf ================================================ # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You 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. # # Default system properties included when running spark-submit. # This is useful for setting default environmental settings. # Example: # spark.master spark://master:7077 # spark.eventLog.enabled true # spark.eventLog.dir hdfs://namenode:8021/directory # spark.serializer org.apache.spark.serializer.KryoSerializer # spark.driver.memory 5g # spark.executor.extraJavaOptions -XX:+PrintGCDetails -Dkey=value -Dnumbers="one two three" ================================================ FILE: benchmarks/in-memory-analytics/latest/files/spark-env.sh ================================================ #!/usr/bin/env bash # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You 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. # # This file is sourced when running various Spark programs. # Copy it as spark-env.sh and edit that to configure Spark for your site. # Options read when launching programs locally with # ./bin/run-example or ./bin/spark-submit # - HADOOP_CONF_DIR, to point Spark towards Hadoop configuration files # - SPARK_LOCAL_IP, to set the IP address Spark binds to on this node # - SPARK_PUBLIC_DNS, to set the public dns name of the driver program # Options read by executors and drivers running inside the cluster # - SPARK_LOCAL_IP, to set the IP address Spark binds to on this node # - SPARK_PUBLIC_DNS, to set the public DNS name of the driver program # - SPARK_LOCAL_DIRS, storage directories to use on this node for shuffle and RDD data # - MESOS_NATIVE_JAVA_LIBRARY, to point to your libmesos.so if you use Mesos # Options read in YARN client/cluster mode # - SPARK_CONF_DIR, Alternate conf dir. (Default: ${SPARK_HOME}/conf) # - HADOOP_CONF_DIR, to point Spark towards Hadoop configuration files # - YARN_CONF_DIR, to point Spark towards YARN configuration files when you use YARN # - SPARK_EXECUTOR_CORES, Number of cores for the executors (Default: 1). # - SPARK_EXECUTOR_MEMORY, Memory per Executor (e.g. 1000M, 2G) (Default: 1G) # - SPARK_DRIVER_MEMORY, Memory for Driver (e.g. 1000M, 2G) (Default: 1G) # Options for the daemons used in the standalone deploy mode # - SPARK_MASTER_HOST, to bind the master to a different IP address or hostname # - PARK_MASTER_OPTS, to set config properties only for the master (e.g. "-Dx=y") # - SPARK_WORKER_CORES, to set the number of cores to use on this machine # - SPARK_WORKER_MEMORY, to set how much total memory workers have to give executors (e.g. 1000m, 2g) # - SPARK_WORKER_PORT / SPARK_WORKER_WEBUI_PORT, to use non-default ports for the worker # - SPARK_WORKER_DIR, to set the working directory of worker processes # - SPARK_WORKER_OPTS, to set config properties only for the worker (e.g. "-Dx=y") # - SPARK_DAEMON_MEMORY, to allocate to the master, worker and history server themselves (default: 1g). # - SPARK_HISTORY_OPTS, to set config properties only for the history server (e.g. "-Dx=y") # - SPARK_SHUFFLE_OPTS, to set config properties only for the external shuffle service (e.g. "-Dx=y") # - SPARK_DAEMON_JAVA_OPTS, to set config properties for all daemons (e.g. "-Dx=y") # - SPARK_DAEMON_CLASSPATH, to set the classpath for all daemons # - SPARK_PUBLIC_DNS, to set the public dns name of the master or workers # Generic options for the daemons used in the standalone deploy mode # - SPARK_CONF_DIR Alternate conf dir. (Default: ${SPARK_HOME}/conf) # - SPARK_LOG_DIR Where log files are stored. (Default: ${SPARK_HOME}/logs) # - SPARK_PID_DIR Where the pid file is stored. (Default: /tmp) # - SPARK_IDENT_STRING A string representing this instance of spark. (Default: $USER) # - SPARK_NICENESS The scheduling priority for daemons. (Default: 0) # - SPARK_NO_DAEMONIZE Run the proposed command in the foreground. It will not output a PID file. # Options for native BLAS, like Intel MKL, OpenBLAS, and so on. # You might get better performance to enable these options if using native BLAS (see SPARK-21305). # - MKL_NUM_THREADS=1 Disable multi-threading of Intel MKL # - OPENBLAS_NUM_THREADS=1 Disable multi-threading of OpenBLAS ================================================ FILE: benchmarks/in-memory-analytics/latest/movielens-als/build.sbt ================================================ name := "movielens-als" version := "2.0" organization := "PARSA" scalaVersion := "2.13.10" artifactName := { (sv: ScalaVersion, module: ModuleID, artifact: Artifact) => artifact.name + "-" + module.revision + "." + artifact.extension } libraryDependencies ++= Seq( "org.apache.spark" %% "spark-core" % "3.3.2", "org.apache.spark" %% "spark-sql" % "3.3.2", "org.apache.spark" %% "spark-mllib" % "3.3.2" ) ================================================ FILE: benchmarks/in-memory-analytics/latest/movielens-als/run_benchmark.sh ================================================ #!/usr/bin/env bash read -r -d '' USAGE << EOS Usage: in-memory-analytics DATASET RATINGS [SPARK_OPTIONS] DATASET is the dataset directory (e.g. /data/ml-latest-small). RATINGS is the rating file (e.g. /data/myratings.csv). SPARK_OPTIONS are passed on to spark-submit. EOS if [[ $# -lt 2 ]]; then echo "$USAGE" exit 1 fi DATASET=$1 shift RATINGS=$1 shift echo "Executing with: DATASET:${DATASET} RATINGS:${RATINGS}" echo " SPARK_OPTIONS:"$@"" exec ${SPARK_HOME}/bin/spark-submit --class MovieLensALS "$@" \ ${BENCHMARK_JAR} $DATASET $RATINGS ================================================ FILE: benchmarks/in-memory-analytics/latest/movielens-als/src/main/scala/MovieLensALS.scala ================================================ import java.io.File import scala.io.Source import org.apache.log4j.Logger import org.apache.log4j.Level import org.apache.spark.SparkConf import org.apache.spark.SparkContext import org.apache.spark.SparkContext._ import org.apache.spark.rdd._ import org.apache.spark.mllib.recommendation.{ALS, Rating, MatrixFactorizationModel} object MovieLensALS { def main(args: Array[String]) : Unit = { Logger.getLogger("org.apache.spark").setLevel(Level.WARN) Logger.getLogger("org.eclipse.jetty.server").setLevel(Level.OFF) if (args.length != 2) { println("Example: /path/to/spark/bin/spark-submit --driver-memory 2g --class MovieLensALS " + "target/scala-*/movielens-als-ssembly-*.jar movieLensHomeDir personalRatingsFile") sys.exit(1) } // set up environment val conf = new SparkConf() .setAppName("MovieLensALS") val sc = new SparkContext(conf) // time the execution val t0 = System.currentTimeMillis // load personal ratings val myRatings = loadRatings(args(1)) val myRatingsRDD = sc.parallelize(myRatings, 1) // load ratings and movie titles val movieLensHomeDir = args(0) val ratingsFile = sc.textFile(new File(movieLensHomeDir, "ratings.csv").toString) val ratingsFileHeader = ratingsFile.first() val ratings = ratingsFile.filter{ line => line != ratingsFileHeader }.map { line => val fields = line.split(",") // format: (timestamp % 10, Rating(userId, movieId, rating)) (fields(3).toLong % 10, Rating(fields(0).toInt, fields(1).toInt, fields(2).toDouble)) } val moviesFile = sc.textFile(new File(movieLensHomeDir, "movies.csv").toString) val moviesFileHeader = moviesFile.first() val movies = moviesFile.filter{ line => line != moviesFileHeader }.map { line => val fields = line.split(",") // format: (movieId, movieName) (fields(0).toInt, fields(1)) }.collect().toMap val numRatings = ratings.count() val numUsers = ratings.map(_._2.user).distinct().count() val numMovies = ratings.map(_._2.product).distinct().count() println("Got " + numRatings + " ratings from " + numUsers + " users on " + numMovies + " movies.") // split ratings into train (60%), validation (20%), and test (20%) based on the // last digit of the timestamp, add myRatings to train, and cache them val numPartitions = 4 val training = ratings.filter(x => x._1 < 6) .values .union(myRatingsRDD) .repartition(numPartitions) .cache() val validation = ratings.filter(x => x._1 >= 6 && x._1 < 8) .values .repartition(numPartitions) .cache() val test = ratings.filter(x => x._1 >= 8).values.cache() val numTraining = training.count() val numValidation = validation.count() val numTest = test.count() println("Training: " + numTraining + ", validation: " + numValidation + ", test: " + numTest) // train models and evaluate them on the validation set val ranks = List(8, 12) val lambdas = List(0.1, 10.0) val numIters = List(10, 20) var bestModel: Option[MatrixFactorizationModel] = None var bestValidationRmse = Double.MaxValue var bestRank = 0 var bestLambda = -1.0 var bestNumIter = -1 for (rank <- ranks; lambda <- lambdas; numIter <- numIters) { val model = ALS.train(training, rank, numIter, lambda) val validationRmse = computeRmse(model, validation, numValidation) println("RMSE (validation) = " + validationRmse + " for the model trained with rank = " + rank + ", lambda = " + lambda + ", and numIter = " + numIter + ".") if (validationRmse < bestValidationRmse) { bestModel = Some(model) bestValidationRmse = validationRmse bestRank = rank bestLambda = lambda bestNumIter = numIter } } // evaluate the best model on the test set val testRmse = computeRmse(bestModel.get, test, numTest) println("The best model was trained with rank = " + bestRank + " and lambda = " + bestLambda + ", and numIter = " + bestNumIter + ", and its RMSE on the test set is " + testRmse + ".") // create a naive baseline and compare it with the best model val meanRating = training.union(validation).map(_.rating).mean() val baselineRmse = math.sqrt(test.map(x => (meanRating - x.rating) * (meanRating - x.rating)).mean()) val improvement = (baselineRmse - testRmse) / baselineRmse * 100 println("The best model improves the baseline by " + "%1.2f".format(improvement) + "%.") // make personalized recommendations val myRatedMovieIds = myRatings.map(_.product).toSet val candidates = sc.parallelize(movies.keys.filter(!myRatedMovieIds.contains(_)).toSeq) val recommendations = bestModel.get .predict(candidates.map((0, _))) .collect() .sortBy(- _.rating) .take(50) var i = 1 println("Movies recommended for you:") recommendations.foreach { r => println("%2d".format(i) + ": " + movies(r.product)) i += 1 } // time the execution val te = System.currentTimeMillis - t0 println("Benchmark execution time: " + te + "ms") // clean up sc.stop() } /** Compute RMSE (Root Mean Squared Error). */ def computeRmse(model: MatrixFactorizationModel, data: RDD[Rating], n: Long): Double = { val predictions: RDD[Rating] = model.predict(data.map(x => (x.user, x.product))) val predictionsAndRatings = predictions.map(x => ((x.user, x.product), x.rating)) .join(data.map(x => ((x.user, x.product), x.rating))) .values math.sqrt(predictionsAndRatings.map(x => (x._1 - x._2) * (x._1 - x._2)).reduce(_ + _) / n) } /** Load ratings from file. */ def loadRatings(path: String): Seq[Rating] = { val lines = Source.fromFile(path).getLines() val ratings = lines.map { line => val fields = line.split(",") Rating(fields(0).toInt, fields(1).toInt, fields(2).toDouble) }.filter(_.rating > 0.0) if (ratings.isEmpty) { sys.error("No ratings provided.") } else { ratings.toSeq } } } ================================================ FILE: benchmarks/media-streaming/client/Dockerfile ================================================ FROM cloudsuite/base-os:ubuntu RUN apt-get update \ && apt-get install -y --no-install-recommends \ bc \ build-essential \ libssl-dev \ && rm -rf /var/lib/apt/lists/* COPY files /root/ RUN set -x \ && mkdir -p /root/build \ && cd /root/build \ && /root/videoperf/configure \ && make \ && make install RUN chmod +x /root/docker-entrypoint.sh RUN rm -rf /output && mkdir -p /output VOLUME ["/output"] RUN rm -rf /videos/logs && mkdir -p /videos/logs VOLUME [ "/videos/logs" ] ENTRYPOINT ["/root/docker-entrypoint.sh"] ================================================ FILE: benchmarks/media-streaming/client/files/docker-entrypoint.sh ================================================ #!/bin/bash set -e # $1: the IP of the server # $2: the number of httperf clients # $3: the total number of sessions # $4: the rate (sessions per seconds) # $5: plain text or encrypted communication, possible values are "PT" and "TLS" if [ "$1" = "bash" ]; then exec $@ else cd /root/run && exec ./benchmark.sh $1 $2 $3 $4 $5 fi ================================================ FILE: benchmarks/media-streaming/client/files/run/benchmark.sh ================================================ #!/bin/bash server_ip=$1 num_clients_per_machine=${2:-4} num_sessions=${3:-100} rate=${4:-10} mode=${5:-TLS} streaming_client_dir=.. #server_ip=$(tail -n 1 hostlist.server) peak_hunter/launch_hunt_bin.sh \ $server_ip \ hostlist.client \ $streaming_client_dir \ $num_clients_per_machine \ $num_sessions \ $rate \ $mode ./process_logs.sh ================================================ FILE: benchmarks/media-streaming/client/files/run/hostlist.client ================================================ localhost ================================================ FILE: benchmarks/media-streaming/client/files/run/hostlist.server ================================================ streaming_server ================================================ FILE: benchmarks/media-streaming/client/files/run/peak_hunter/launch_hunt_bin.sh ================================================ #!/bin/bash videoServerIp="$1" hostFileName="$2" remoteOutputPath="$3" numClientsPerHost="$4" totalNumSessions="$5" rate="$6" mode="$7" if [ $# -ne 7 ]; then echo "Usage: launch_hunt_bin.sh " exit fi # Distribute the load numHosts=$(wc -l < $hostFileName) numTotalClients=$[$numHosts*$numClientsPerHost] NumSessions=$[$totalNumSessions/$numTotalClients] rate=`echo "scale=2; $rate/$numTotalClients" | bc` echo "Total clients = $numTotalClients" echo "Total number of sessions = $totalNumSessions" outputDir="/output" backUpStdoutDir="/output-stdout" rm -rf "$outputDir/*" "$backUpStdoutDir" mkdir -p "$outputDir" "$backUpStdoutDir" # Launches remote with the specified number of sessions. function launchRemote () { totalConns=0 totalErrors=0 numSessions="$1" $(dirname $0)/launch_remote.sh $videoServerIp $hostFileName $remoteOutputPath $numClientsPerHost $numSessions $rate $mode if [ $? -ne 0 ]; then echo 'Failed launching remote... exiting.' exit fi # Open each file in output directory totalConns=0 for outputFile in $outputDir/*; do numConns="$(grep 'Total: connections' $outputFile | awk '{print $3}')" numErrors="$(grep 'Errors: total' $outputFile | awk '{print $3}')" totalConns=$[totalConns+numConns] totalErrors=$[totalErrors+numErrors] done if [ $totalConns -eq 0 ]; then echo "No log is found from the log folder: $outputDir" echo "Please check the the folder exists, or whether any request is sent during the test" else percFailure=$[$totalErrors*100/$totalConns] echo "Total connections = $totalConns" echo "Total errors = $totalErrors" echo "Percentage failure = $percFailure" if [ "$percFailure" -gt 5 ]; then cp $backUpStdoutDir/* $outputDir sleep 10 else cp $outputDir/* $backUpStdoutDir fi fi } # Test for NumSessions launchRemote $NumSessions exit 0 ================================================ FILE: benchmarks/media-streaming/client/files/run/peak_hunter/launch_remote.sh ================================================ #!/bin/bash videoServerIp="$1" hostFileName="$2" remoteOutputPath="$3" numClientsPerHost="$4" numSessions="$5" rate="$6" mode="$7" if [ $# -ne 7 ]; then echo "Usage: launch_remote.sh " exit fi if [ $mode = "PT" ];then mode="--port 80" elif [ $mode = "TLS" ]; then mode="--ssl --port 443 --ssl-ciphers TLS_AES_128_GCM_SHA256" else echo "invalid encryption mode flag" exit fi # TODO: this needs to be fixed - need static correspondence between log, ratio, and ip logs=$(echo /videos/logs/cl* | sed -e 's/ /,/g') while read hostLine do sIFS=$IFS; IFS=' :'; declare -a d=($hostLine); IFS=$sIFS host=${d[0]} #ips=$(echo ${d[@]:1:100} | sed -e 's/-[^ ]*//g' -e 's/ /,/g') #ssh $host "sudo mkdir -m 0777 -p $remoteOutputPath/results" echo "Launching $numClientsPerHost clients on $host"; for i in $(seq 1 $numClientsPerHost) do cmd="httperf --hog --server $videoServerIp --videosesslog=[$logs],[0.1,0.3,0.4,0.2],[localhost,localhost,localhost,localhost] --epoll --recv-buffer=524288 $mode --output-log=/output/result$i.log --num-sessions=$numSessions --rate=$rate 2>>/output/bt$i.trace" # > output-stdout/stdout$i" echo "Running command $cmd" eval $cmd & done wait done < "$hostFileName" ================================================ FILE: benchmarks/media-streaming/client/files/run/process_logs.sh ================================================ #!/bin/bash output_dir=${1:-/output} nFiles=0 nRequests=0 nReplies=0 replyRateAcc=0 replyTimeAcc=0 netIOAcc=0 for resultFile in $output_dir/*.log; do if [ -f $resultFile ]; then nFiles=$(echo $nFiles + 1 | bc) x=$(grep 'Total:' $resultFile | awk '{print $5}') nRequests=$(echo "$nRequests" + "$x" | bc) x=$(grep 'Total:' $resultFile | awk '{print $7}') nReplies=$(echo "$nReplies + $x" | bc) x=$(grep 'Reply rate' $resultFile | awk '{print $7}') replyRateAcc=$(echo "$replyRateAcc + $x" | bc) x=$(grep 'Reply time' $resultFile | awk '{print $5}') replyTimeAcc=$(echo "$replyTimeAcc + $x" | bc) x=$(grep 'Net I/O:' $resultFile | awk '{print $3}') netIOAcc=$(echo "$netIOAcc + $x" | bc) fi done if [ $nFiles -eq 0 ]; then echo "No log is found from the log folder: $output_dir" echo "Please check the the folder exists, or whether any request is sent during the test" else echo Requests: $nRequests echo Replies: $nReplies echo Reply rate: $(echo "scale=2; $replyRateAcc / $nFiles" | bc) echo Reply time: $(echo "scale=2; $replyTimeAcc / $nFiles" | bc) echo Net I/O: $netIOAcc for btFile in $output_dir/*.trace; do if [ -f $btFile ]; then cat $btFile | /root/videoperf/bt2line $(which httperf) fi done fi ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/AUTHORS ================================================ David Mosberger (main sources) Martin Arlitt (SSL support) Stephane Eranian (wlog URI generator) Richard Carter (wsesslog workload generator) ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/COPYRIGHT ================================================ GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/ChangeLog ================================================ 2012-10-30 Tim Brecht * Version 0.8.6b and 0.8.6c * Removed some debugging statements * Did a lot of work to get clean compilation on multiple platforms so we can turn on -Werror 2012-10-17 Tim Brecht * Version 0.8.6 * Fixed weird issue with s->id being long and comparing with u_long and comparison failing * Added code from Tyler Szepesi for tracking statistics based on each call and for specifying a timeout for each entry in a wsession log file. From Jim Summers for elimintating ramp up and ramp down periods, and for staggering the starts of multiple clients so they aren't in sync, and for adding pacing requests to wsession log files. 2011-12-14 Tim Brecht * Version 0.8.5 * TBB - added code from Adam Gruttner for handling headers in wsesslog files. 2004-10-21 Tim Brecht Vikram Saletore * Version 0.8.4 * TBB fixed problem with non blocking connects all being treated as though they were successful * TBB and VAS added counters to keep track of the number of connections that are actually connected (to track current connected and max connected). 2003-10-3 Tim Brecht * httperf.h changed version number * modified configure file to include -ldl with cyrpto for static binaries * added -I/usr/include/kerberos for compilation on RH 9.0 * fixed some of the error messages * added debugging messages * modified the way zero bytes files are handled (this modification doesn't work if a trailer is also included but it works for our needs) * added a few include to provide prototypes for exit() David Pariag * added rate-interval to permit finer grained printing of reply rates 2000-10-31 David Mosberger * Version 0.8 released. * core.c (do_recv) [!HAVE_SSL]: Avoid referncing param.use_ssl. (do_send): Ditto. * core.c (core_ssl_connect): Print error message if SSL connect fails. ERR_print_errors_fp() may not print anything if there error is due to, e.g., trying to connect to a non-existent port. * httperf.c (main): Initialize port to -1. Once parameters have been processed, port defaults to 443 if SSL is in use, 80 otherwise. 2000-10-30 David Mosberger * httperf.man: Update man-page with new options (based on Martin's descriptions. * httperf.c (usage): Mention --port. 2000-10-27 David Mosberger * httperf.man: Mention request summary in description of --print-request. * stat/print_reply.c (print_request): Print request header/content summary line. * httperf.c (usage): Bring in sync with implemented options (Martin's patch). (longopts): Order in alphabetical order (Martin's patch). 2000-10-25 David Mosberger * stat/print_reply.c (flush_print_buf): New. (Call_Private_Data): New. (CALL_PRIVATE_DATA): New. (call_private_data_offset): New. (print_buf): Rewrite to support line-buffering and new output format. (call_destroyed): New. (print_reply_hdr): New (based on Martin's original version). (send_raw_data): Ditto. (recv_raw_data): Ditto. (recv_stop): Print reply summary (based on Martin's version). (init): Update to support the new print options. * httperf.c: Replace --print-replies/--print-request with more general versions of these options. * httperf.man: Add info on new --print-reply and --print-request options. 2000-10-24 David Mosberger * httperf.c (main): Initialize ssl_ctx. (main): Use SSLv3_client_method() instead of SSLv23_client_method(). The latter doesn't work. * httperf.h (ssl_ctx): New global variable. * conn.h [HAVE_SSL]: Drop unnecessary includes of , , , and . Drop per-connect "ctx" member (it's global now). * conn.c (conn_init): Create SSL connection info and set cipher list (if necessary). * core.c (core_ssl_connect): Don't create SSL connection info here (done in conn.c now). Always tell SSL about the file descriptor of the socket. * sess.c (sess_deinit) [HAVE_SSL]: Free SSL info if it exists. * gen/session.c (create_conn): If param.ssl_reuse is in effect, re-use SSL session if we have one or update session info with newly created SSL session. * httperf.c [HAVE_SSL]: Include . (main): Call RAND_seed() with a zero buffer. 2000-10-23 David Mosberger * conn.c (conn_init): Don't initialize conn->ssl to zero---that has been done by object_new() already. * gen/session.c (create_conn): If reusing SSL session ids, create SSL structure and save SSL info in session structure. * sess.c (sess_deinit) [HAVE_SSL]: Free SSL session if it's non-NULL. * httperf.h: Declare "use_ssl" only if HAVE_SSL is defined. Add ssl_no_reuse and ssl_cipher_list. * httperf.c (struct longopts): Add --ssl-no-reuse and ssl-ciphers. (main): Handle --ssl-cipher_list and --ssl-no-reuse options. 2000-10-19 David Mosberger * core.c (core_ssl_connect): Bring debug messages in sync with rest of httperf. If s->ssl exists already, skip right to SSL_connect(). If SSL_connect() returns SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE, mark the appropriate fd set as active and return immediately to wait for more data. Use ERR_print_errors_fp() to print SSL-related errors. (core_loop): Check for S_CONNECTING state before doing anything else. * README: Document configuration option "--enable-debug". * configure.in: Add support for --enable-debug. 2000-10-16 David Mosberger * configure.in: Add AC_TYPE_LONG_LONG check (defines u_wide as "unsigned long long" if the compiler can grok it, "unsigned long" otherwise). * aclocal.m4: New file. * stat/basic.c: Include "config.h". (struct basic): Change type of hdr_bytes_received, reply_bytes_received, and footer_bytes_received from size_t to u_wide. (dump): Change type of total_size to u_wide. 2000-10-11 David Mosberger * httperf.h (VERSION): Change to 0.8beta. * configure.in: New file. * Makefile.in: Ditto. * stat/Makefile.in: Ditto. * gen/Makefile.in: Ditto. * lib/Makefile.in: Ditto. 2000-08-29 David Mosberger * httperf.c (main): Call core_exit() on a SIGINT. 2000-08-21 David Mosberger * core.c (core_init): Bound maximum number of open files to FD_SETSIZE. 2000-04-25 David Mosberger * httperf.c (main): Add a call to fpsetmask(0) to get non-finite IEEE arithmetic to work on older versions of FreeBSD. 1998-12-21 David Mosberger * Version 0.7 released. * Makefile (install): New make target. * httperf.h (VERSION): Define as "0.7". * gen/wsesslog.c (parse_config): Remove blank in sscanf() format since this caused problems on FreeBSD and NetBSD. This bug was reported by Stephane Eranian. 1998-12-08 David Mosberger * httperf.c (struct longopts): Add option "method". (usage): Document option --method. (main): Handle --method. * httperf.h (struct Cmdline_Params): New member "method". * gen/misc.c: Renamed from add_header.c. This file now implements both --add-header and --method. 1998-11-23 David Mosberger * httperf.c (longopts): New option "add-header". (main): Handle --add-header. * httperf.h (struct Cmdline_Params): New member "additional_header". * gen/add_header.c: New file. 1998-09-18 David Mosberger * gen/session.c (call_done): (conn_failed): Call create_conn() instead of sess_failure() in case param.retry_on_failure is set and the connection has not been successful (received at least one good response) * gen/wsess.c (call_destroyed): Call sess_dec_ref() only if session didn't fail. 1998-09-14 David Mosberger * README: Replace "session" with "connection" and "call" with "request" to reflect current terminology (reported by Christian Petit). Also fixed various other typos and grammatical problems. 1998-09-11 David Mosberger * gen/session.c (call_done): When param.retry_on_failure is set, re-issue call instead of causing session to fail. * httperf.c (usage): Add --retry-on-failure option. (struct longopts): Ditto. * httperf.man: Document --retry-on-failure option. 1998-07-23 David Mosberger * stat/sess_stat.c: Use sess->failed instead of maintaining private session-failure flag. 1998-07-21 David Mosberger * sess.c (sess_failure): Don't signal EV_SESS_FAILED more than once per session. * core.c (do_send): Clear c->recvq_next. This is necessary now because the same call may be issued multiple times (due to connection failures). Hence there is no longer a guarantee that c->recvq_next has been cleared by object_new(). (do_send): Rename s to conn and c to call. 1998-07-20 David Mosberger-Tang * core.c (do_recv): Set s->state to S_REPLY_DONE when done with an HTTP/1.0 response (mirrors code in http_process_reply_bytes()). (do_recv): No need to check for nread == 0. * stat/basic.c (init): Print basic.conn_lifetime_min only if basic.num_lifetimes > 0. * core.c (core_close): Fix typo (call -> all). 1998-07-08 David Mosberger * core.c (do_send): Set s->state to S_REPLY_STATUS only if this is the first send---we don't want to interfere with the parsing of an in-progress reply. 1998-06-19 David Mosberger * Version 0.6 released. * gen/wsesslog.c (issue_calls): Limit `to_create' by the number of calls that the session can queue. * gen/session.c (session_max_qlen): New function. (session_current_qlen): Ditto. (max_qlen): New variable. * httperf.man: Fix typos. 1998-06-18 David Mosberger * gen/session.c (MAX_CONN): Up MAX_CONN to 16. * object.c (object_new): panic() instead of assert(0) when encountering an unknown object type. * gen/wsesslog.c (user_think_time_expired): Remove stale comment. * gen/sess_cookie.c (struct Call_Private_Data): New member cookie. (call_recv_hdr): Remove padding bogosity. (call_issue): Copy cookie from session to call object. 1998-06-17 David Mosberger * timer.c (timer_cancel): Instead of an assertion failure, print a message on stderr when timer_cancel(t) is called from within a timeout handler t. * Feedback from Dick Carter: * gen/wsesslog.c (parse_config): Remove stale comment. * httperf.h: Fix typo in comment for min_iat. * httperf.c (usage): Fix typo in --period args. * call.c (call_append_request_header): Fix typo in debug message. 1998-06-09 David Mosberger * stat/print_reply.c: New file. * stat/sess_stat.c: Ditto. * stat/wsess_stat.c: Remove. * stat/basic.c: Move stats macros into stats.h. (RATE_INTERVAL): Remove. (interval_start): Ditto. (perf_sample): Rename from sample_rate(). (conn_fail): Count EPIPE as a `connection reset' error. (init): Register perf_sample as handler for EV_PERF_SAMPLE. Remove scheduling of performance sampling timer. (dump): Print connection lifetime histogram only if verbose > 1. Print average connection length in number of replies/connection. * stat/stats.h: New file. * stat/basic.c: Add copyright message. * stat/Makefile (libstat.a): Mention sess_stat.o and print_reply.o. * object.c: New file. * object.h: Ditto. * sess.c: Ditto. * sess.h: Ditto. * httperf.h (VERSION): Up version number to 0.6. (object_is_conn): Remove (now in object.h). (object_is_call): Ditto. (enum Object_Type): Ditto. (struct Object): Ditto. (object_type_size): Ditto. (struct Cmdline_Params): New mebers max_piped, max_conns, print_replies, and session_cookies. * httperf.c (perf_sample_start): New variable to keep track of when latest sample interval started. (struct longopts): Add entries for max-connections, max-piped-calls, print-replies, and session-cookies. (usage): Update usage() message. (perf_sample): New function. (main): Remove uri_wsesslog generator. Add sess_stat stats collector. Handle --max-connections, --max-piped, --print-replies and --session-cookies. Start performance sampling timer. * http.c (get_line): Use sizeof (s->line_buf) instead of s->line_buf_size. (parse_status_line): Do strcmp() to find out whether call was a HEAD request. Ignore `100 Continue' replies. * gen/wsesslog.h: Remove. * gen/wsess.c: Modify to take advantage of session manager (gen/session.c). * gen/wsesslog.c: Modify to take advantage of session manager and merge with uri_wsesslog.c. * gen/uri_wlog.c (set_uri): Use call_set_uri(). * gen/uri_wset.c (set_uri): Ditto. * gen/uri_fixed.c (uri_len): New variable. (set_uri): Use call_set_uri(). (init): Initialize uri_len. * gen/session.c: New file. * gen/session.h: Ditto. * gen/sess_cookie.c: New file (based on wsess.c). * gen/conn_rate.c: File renamed from sess_rate.c. * gen/call_seq.c: Modify to take advantage of reference counting. * gen/Makefile (libgen.a): Remove uri_wsesslog (it's part of wsesslog now). * gen/uri_wsesslog.c: Remove. * gen/uri_wsesslog.h: Ditto. * event.h (Event_Type): New member EV_PERF_SAMPLE for performance sampling (invoked once every 5 seconds). Rename EV_USER_NEW to EV_SESS_NEW and EV_USER_DESTROYED to EV_SESS_DESTROYED. New member EV_SESS_FAILED that is signalled when a session fails. * core.c (do_send): Remove left-over assert()ion. (do_send): Preserve io vector element that is being sent in iov_saved. Call call_dec_ref() when the connection is closing. (recv_done): Rename `c' to `call' and invoke call_dec_ref(). (do_recv): Call conn_failure() only if errno != EAGAIN (for Linux). (core_send): Add `conn' argument. Fill in req.iov[IE_HOST] and req.iov[IE_PROTL] only (rest has been filled in by call_set_* macros). Call call_inc_ref() once the call is ready. (core_close): Rename `s' to `conn'. Destroy pending calls calls on the sendq and recvq by calling call_dec_ref(). Call conn_dec_ref() at the end. (core_loop): Obtain a reference to the connection object for the duration of read & write processing. * conn.h: Include . (MAX_HDR_LINE_LEN): New macro. (struct Conn): Remove member first_owned and line_size. Replace line_buf pointer with line_buf array. (conn_init): Declare. (conn_deinit): Ditto. (conn_new): New macro. (conn_inc_ref): Ditto. (conn_dec_ref): Ditto. * conn.c: Remove include of and . (conn_new): Remove. (conn_destroy): Ditto. (conn_init): New function. (conn_deinit): Ditto. * call.h: (enum HTTP_Method): Remove. Include . (struct Call): Remove members loc_len, loc, uri_len, uri, orig_host, extra_hdrs, contents_len, contents. New member: iov_saved. (call_init): Declare. (call_deinit): Ditto. (call_new): New macro. (call_inc_ref): Ditto. (call_dec_ref): Ditto. (call_set_method): Ditto. (call_set_location): Ditto. (call_set_uri): Ditto. (call_set_contents): Ditto. * call.c (call_method_name): Remove. (free_call_list): Remove. (call_new): Remove. (call_init): New function. (call_deinit): Ditto. (call_append_request_header): Fill req.iov[IE_FIRST_HEADER + num_hdrs] instead of req.extra_hdrs[num_hdrs]. * Makefile (HTTPERF): Mention object and sess. 1998-05-29 David Mosberger * Version 0.5 released. * core.c (core_send): Fix setup of IE_METHOD and insert blank character in IE_BLANK. * call.h (enum IOV_Element): Add IE_BLANK. 1998-05-27 David Mosberger * timer.c: Rename t_next to t_curr. (timer_tick): Set t_next _after_ invoking the callback. This allows the callback to cancel all other timers (except itself). (timer_cancel): Add assertion to ensure that timer_cancel() is not called from within the handler of a given timer. * httperf.h (enum Dist_Type): New type. (struct Rate_Info): Ditto. (struct Cmdline_Params): Change type of RATE member from Time to Rate_Info. New member WSESSLOG. (panic): Declare. * httperf.h (VERSION): Up version number to 0.5. * httperf.c: Include and . New options: close-with-reset, period, wsesslog. (usage): Add usage message for new options. (panic): New function. (main): Declare wsesslog, uri_wsesslog, and wsesslog_stat. Initialize param.rate.dist with DETERMINISTIC. Handle --period and --wsesslog options. Fix typo: user think time is 3rd, not 4th parameter in wsess parameter list. (main): Call timer_tick() after initializating the statistic collectors and workload generators so our notion of the current time is reasonably accurate. * gen/wsess.c (req_create): Use call_append_request_header(). (start): Initialize rg_sess.rate with ¶m.rate. * gen/uri_wsesslog.h: New file (by Dick Carter). * gen/uri_wsesslog.c: Ditto. * gen/wsesslog.h: Ditto. * gen/wsesslog.c: Ditto. * gen/uri_wlog.c: Drop inclusion of . Move panic() from here to httperf.c. * gen/sess_rate.c (start): Initialize rg.rate with ¶m.rate. * gen/rate.h: New member next_interarrival_time. New member xsubi. Replace PERIOD member with RATE member. (rate_generator_stop): Drop second argument (RATE). * gen/rate.c: Include , , and . (next_arrival_time_det): New function. (next_arrival_time_uniform): Ditto. (next_arrival_time_exp): Ditto. (tick): Invoke (*next_arrival_time)() to determine next delay. (rate_generator_start): Initialize rg->xsubi based on param.client.id. Initialize rg->next_interarrival_time based on desired distribution. * gen/Makefile (libgen.a): Mention wsesslog.o and uri_wsesslog.o * core.c (core_connect): Don't rely on realloc(0, SIZE) doing the right thing. (core_connect): Clear newly allocated sd_to_conn elements after allocating them. (core_send): Use call_method_name. Copy in defined c->req.extra_hdrs[i] iovecs. Copy in IE_CONTENT iovec. * call.h: New value HM_LEN. (MAX_EXTRA_HEADERS): New macro. Replace IE_HEADERS with IE_FIRST_HEADER and IE_LAST_HEADER. Make extra_hdrs an array of `struct iovec'. New member num_extra_hdrs. (call_append_request_header): Declare new function. * call.c: New array. (call_append_request_header): New function. 1998-05-26 David Mosberger * COPYRIGHT: Add 1998 as copyright year. * stat/basic.c (dump): If no connections have been created, print 0.0 for minimm connection lifetime. This avoids a core-dump under FreeBSD, which seems to have a problem printing IEEE infinity. 1998-05-22 David Mosberger * call.c (method_name): New variable. 1998-04-27 David Mosberger * core.c (do_recv): Ignore EAGAIN errors---Linux 2.0.32 sometimes returns EAGAIN on a read() if a previous write() resulted in EAGAIN. * AUTHORS: New file. 1998-03-24 David Mosberger * gen/wsess.c (call_done): Also fall back to non-persistent session if c->req.version < HTTP/1.1. 1998-03-18 David Mosberger * httperf.c (usage): Fix typo: --recv-buffer -> --send-buffer. * gen/wsess.c (dump): Rename "Sess" to "Session" in statistics output. * core.c (core_connect): Turn on closing with RESET only when param.close_with_reset is set. 1998-03-17 David Mosberger * stat/basic.c (dump): In "Total" line, rename "call" to "req". * Version 0.41 released. * core.c: Include after to get it to compile under FreeBSD (which seems to have a broken libc). * stat/basic.c (dump): Complete renaming of "session" to "call". Rename "Call" to "Request". 1998-03-16 David Mosberger * Version 0.4 released. * httperf.h (VERSION): Change version number to 0.4. * httperf.c: (longopts): Add --http-version. (main): Initialize param.http_version to HTTP/1. Support parsing of --http-version option. Echo --http-version option if version other than 1.1 is selected. * httperf.h (struct Cmdline_Params): New member HTTP_VERSION. * core.c (core_send): Support generation of HTTP/1.0 requests. * Patches by Stephane Eranian: * httperf.man: Mention --wlog parameter. * Makefile (clean): Use $(MAKE) instead of make. 1998-03-12 David Mosberger * httperf.c: Renamed Session to Conn to avoid confusion between user sessions and TCP connections. 1998-03-02 David Mosberger * gen/wsess.c (user_destroy): Signal EV_USER_DESTROYED. (user_create): Signal EV_USER_NEW. (start): Register rate-generator with event EV_USER_DESTROYED instead of EV_SESSION_DESTROYED. * event.h: New events EV_USER_NEW and EV_USER_DESTROYED. * event.c: Ditto. 1998-02-27 David Mosberger * session.h: Remove unused first_call member. 1998-02-26 David Mosberger * gen/wsess.c (call_recv_hdr): Always check for Connection: and Set-Cookie: headers (not just for first call). (req_create): Modify to support bursts. (user_connect): Ditto. (sess_destroyed): Ditto. (call_destroyed): Ditto. 1998-02-25 David Mosberger * core.c (lffs): Fix lffs() so it returns 0 when no bits at all are set in a 64 bit long. (set_active): Set recvq timeout if timeout==0.0 (the old code failed to timeout connections that were waiting for replies). 1998-02-23 David Mosberger * Version 0.3 released. * timer.c (timer_now_forced): New function. * httperf.h (Cmdline_params): New member burst_len. * httperf.c: New option --burst-length. At present, only gen/call_seq.c supports this (gen/wsess does not). * gen/wsess.c (struct User): New members: found_close_hdr, conn_start, call_start, and cookie. (req_create): Insert cookie as extra header if there is one. (call_recv_hdr): New function. Looks for "Connection: close" and "Set-Cookie:" headers. * gen/call_seq.c (Sess_Private_Data): New member "num_finished". (issue_calls): Add support for --burst-len parameter. (call_destroyed): Ditto. * core.c (SYSCALL): Call timer_now_forced() instead of timer_now(). (core_connect): Keep track of longest back-to-back burst. (core_connect): Set SO_LINGER option so that TCP RST is sent when closing the socket. This avoids the client melting down on HP-UX 10.20 due to a large number of TCP connections in TIME_WAIT state (HP-UX is broken as far as bind()/connect() is concerned when there are many TCP control blocks). (core_exit): Print maximum connect burst length. * core.c (max_burst_len): New variable to keep track of longest back-to-back burst generated (large bursts are usually a sign of the client being overloaded). 1998-02-13 David Mosberger * stat/basic.c (sess_fail): Print one unexpected error number per execution, independent of DBG. 1998-02-06 David Mosberger * core.c (do_send): Maintain sendq_tail & recvq_tail. (core_send): Ditto. (recv_done): Ditto. * session.h (Session): New members SENDQ_TAIL and RECVQ_TAIL. * core.c (set_active): Set watchdog timer to the minimum of the timeout of the request being sent and that being received (if such requests exist). (do_send): Set c->timeout. (core_connect): Ditto. (core_send): Ditto. * call.h: Replace (unused) WATCHDOG member with TIMEOUT. * timer.c (timer_schedule): Handle negative delays gracefully. 1998-01-28 David Mosberger * Version 0.2 released to SixFlags team. 1998-01-26 David Mosberger * gen/call_seq.c (sess_closed): New function. (init): Register sess_closed() so we notice when session closes prematurely. 1998-01-21 David Mosberger * httperf.c (main): Don't quit after printing version information---it's useful to run a test and have this info as well. 1998-01-14 David Mosberger * stat/basic.c (dump): Add num_sock_reset to total error count. 1998-01-12 David Mosberger * stat/basic.c (struct basic): New member num_sock_reset. (sess_fail): Increment num_sock_reset for ECONNRESET. (dump): Print num_sock_reset. * core.c (do_recv): Call session_failure() when reading < 0 bytes. * stat/basic.c (sess_fail): Print error number when getting an unexpected errno and DBG > 0. 1998-01-09 David Mosberger * httperf.c (main): Print only one newline (second newline is printed by stat collectors). * stat/basic.c (dump): Print session lifetime histogram first (so it goes right after the rate output). 1998-01-08 David Mosberger * core.c (port_get): Recode so port numbers are returned in strictly increasing order (until a wraparound after 65535 occurs). This avoids problems with NT 4.0 which disallows reusing the port pair of a properly shut down TCP connection (which creates problems when testing an NT server with clients running on HP-UX or similar platforms). 1998-01-07 David Mosberger * gen/sess_rate.c: Adapt to use rate.c. * timer.c (timer_schedule): Adjust "delay" if realtime has grown bigger than next_tick (meaning that "spoke" is behind). * call.c (call_destroy): prev wasn't updated in the search loop. 1998-01-06 David Mosberger * stat/basic.c (dump): Print minmum rate as zero if there are no rate samples. 1997-12-23 David Mosberger * stat/basic.c (struct basic): Add members num_reply_rates, reply_rate_sum, reply_rate_sum2, reply_rate_min, and reply_rate_max. (interval_start, num_replies): New vars. (sample_rate): New function to sample reply rate. (init): Schedule rate sampler. (dump): Print min, avg, max, and stddev of sampled reply rate. * httperf.c: Add --client and --think-timeout options. 1997-12-17 David Mosberger * http.c (parse_data): Return TRUE to indicate that all bytes (of present chunk) have been received (instead of setting state to S_REPLY_DONE). * httperf.h (ALIGN): Fix macro (need AND with _complement_...). * http.c (xfer_chunked): Fix typo: check for content_bytes >= content_length (not vice versa). * uri_wset.c (set_uri): Fix uri_len computation. * sess_rate.c (destroyed): Fix typo: test for param.rate <= 0 (not <0). ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/Makefile ================================================ # Generated automatically from Makefile.in by configure. SHELL=/bin/sh srcdir = . top_srcdir = . top_builddir = . prefix = /usr/local bindir = ${exec_prefix}/bin mandir = ${prefix}/man SUBDIRS = lib gen stat CC = gcc RANLIB = ranlib MKDIR = $(top_srcdir)/mkinstalldirs INSTALL = /usr/bin/install -c INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 # INCLUDES = -I$(top_srcdir)/include -I$(top_builddir) -I$(top_srcdir) -I$(top_srcdir)/lib INCLUDES = -I$(top_srcdir)/include -I$(top_builddir) -I$(top_srcdir) -I$(top_srcdir)/lib -I/usr/kerberos/include DEFS = -DHAVE_CONFIG_H CPPFLAGS = -DNDEBUG -D_GNU_SOURCE -D_XOPEN_SOURCE CFLAGS = -g -O2 -Wall LDFLAGS = LIBS = -lssl -lcrypto -lm ifeq (x86_64, ia64) CPPFLAGS += -DIA64 endif # Uncomment this to keep track of time spent in system calls #DEFS += -DTIME_SYSCALLS # Uncomment this to have httperf wait nicely when doing a select() DEFS += -DDONT_POLL # Uncomment this to enable --use-cpu-mask functionality (requires OS support) DEFS += -DHAVE_SCHED_AFFINITY -DHAVE_EPOLL # Uncomment this to enable tracking statistics about each call (request) DEFS += -DUW_CALL_STATS # Uncomment this to enable session log file specified dynamic timeouts DEFS += -DUW_DYNOUT # Uncomment this to enable statistics that ignore specified ramp up and ramp down periods #DEFS += -DUW_STABLE_STATS CPPFLAGS += -DBIG_FD_SETSIZE # Uncomment this if you want to enable # --idle-connections N which starts an idleconn process # on the same machine. Can be used with trun's IDLERATE and IDLECONN. #CPPFLAGS += -DIDLECONN COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) LINK = $(CC) $(LDFLAGS) -o $@ .c.o: $(COMPILE) $< HTTPERF_OBJS = httperf.o object.o call.o conn.o sess.o core.o event.o \ http.o timer.o sys_sched_affinity.o TTEST_OBJS = ttest.o timer.o all: all-recursive httperf idleconn httperf: $(HTTPERF_OBJS) gen/libgen.a stat/libstat.a lib/libutil.a $(LINK) $(HTTPERF_OBJS) \ gen/libgen.a stat/libstat.a lib/libutil.a $(LIBS) idleconn: idleconn.o $(LINK) idleconn.o $(LIBS) install: install-recursive httperf $(MKDIR) $(bindir) $(mandir)/man1 $(INSTALL_PROGRAM) httperf $(bindir)/httperf $(INSTALL_DATA) $(srcdir)/httperf.man $(mandir)/man1/httperf.1 ttest: ttest.o timer.o clean: clean-recursive rm -f $(HTTPERF_OBJS) $(TTEST_OBJS) idleconn.o httperf idleconn ttest distclean: distclean-recursive rm -f *~ all-recursive install-recursive clean-recursive distclean-recursive \ depend-recursive: @for subdir in $(SUBDIRS); do \ target=`echo $@ | sed s/-recursive//`; \ echo making $$target in $$subdir; \ (cd $$subdir && $(MAKE) $$target) \ || case "$(MFLAGS)" in *k*) fail=yes;; *) exit 1;; esac; \ done && test -z "$$fail" .PHONY: all install clean distclean depend \ all-recursive install-recursive clean-recursive distclean-recursive \ depend-recursive ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/Makefile.in ================================================ SHELL=/bin/sh VPATH = @srcdir@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ top_builddir = . prefix = @prefix@ bindir = @bindir@ mandir = @mandir@ SUBDIRS = lib gen stat CC = @CC@ RANLIB = @RANLIB@ MKDIR = $(top_srcdir)/mkinstalldirs INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ # INCLUDES = -I$(top_srcdir)/include -I$(top_builddir) -I$(top_srcdir) -I$(top_srcdir)/lib INCLUDES = -I$(top_srcdir)/include -I$(top_builddir) -I$(top_srcdir) -I$(top_srcdir)/lib -I/usr/kerberos/include DEFS = @DEFS@ CPPFLAGS = @CPPFLAGS@ CFLAGS = @CFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ ifeq (@target_cpu@, ia64) CPPFLAGS += -DIA64 endif # Uncomment this to keep track of time spent in system calls #DEFS += -DTIME_SYSCALLS # Uncomment this to have httperf wait nicely when doing a select() DEFS += -DDONT_POLL # Uncomment this to enable --use-cpu-mask functionality (requires OS support) DEFS += -DHAVE_SCHED_AFFINITY -DHAVE_EPOLL # Uncomment this to enable tracking statistics about each call (request) DEFS += -DUW_CALL_STATS # Uncomment this to enable session log file specified dynamic timeouts DEFS += -DUW_DYNOUT # Uncomment this to enable statistics that ignore specified ramp up and ramp down periods #DEFS += -DUW_STABLE_STATS CPPFLAGS += -DBIG_FD_SETSIZE # Uncomment this if you want to enable # --idle-connections N which starts an idleconn process # on the same machine. Can be used with trun's IDLERATE and IDLECONN. #CPPFLAGS += -DIDLECONN COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) LINK = $(CC) $(LDFLAGS) -o $@ @SET_MAKE@ .c.o: $(COMPILE) $< HTTPERF_OBJS = httperf.o object.o call.o conn.o sess.o core.o event.o \ http.o timer.o sys_sched_affinity.o TTEST_OBJS = ttest.o timer.o all: all-recursive httperf idleconn httperf: $(HTTPERF_OBJS) gen/libgen.a stat/libstat.a lib/libutil.a $(LINK) $(HTTPERF_OBJS) \ gen/libgen.a stat/libstat.a lib/libutil.a $(LIBS) idleconn: idleconn.o $(LINK) idleconn.o $(LIBS) install: install-recursive httperf $(MKDIR) $(bindir) $(mandir)/man1 $(INSTALL_PROGRAM) httperf $(bindir)/httperf $(INSTALL_DATA) $(srcdir)/httperf.man $(mandir)/man1/httperf.1 ttest: ttest.o timer.o clean: clean-recursive rm -f $(HTTPERF_OBJS) $(TTEST_OBJS) idleconn.o httperf idleconn ttest distclean: distclean-recursive rm -f *~ all-recursive install-recursive clean-recursive distclean-recursive \ depend-recursive: @for subdir in $(SUBDIRS); do \ target=`echo $@ | sed s/-recursive//`; \ echo making $$target in $$subdir; \ (cd $$subdir && $(MAKE) $$target) \ || case "$(MFLAGS)" in *k*) fail=yes;; *) exit 1;; esac; \ done && test -z "$$fail" .PHONY: all install clean distclean depend \ all-recursive install-recursive clean-recursive distclean-recursive \ depend-recursive ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/NEWS ================================================ -*-Mode: outline-*- * New in version 0.8: ** httperf is now released under the GNU General Public License (GPL). ** Preliminary support for SSL (Secure Socket Layer). See README for details. ** New options (see man-page for details): --print-reply (replaced --print-replies) --print-request --ssl --ssl-ciphers --ssl-no-reuse * New in version 0.7: ** New options (see man-page for details): --add-header --method --retry-on-failure ** Bug fixes - fixed some segfaults in the session workload generator - specifying option --session-cookie when not using a session workload generator now prints an error message instead of core dumping * New in version 0.6: ** New options (see man-page for details): --max-connections --max-piped-calls --print-replies --session-cookies ** Cookie support now must be requested explicitly when using a session-based workload generator. To do this, specify option --session-cookie. * New in version 0.5: ** Normal connection closing is the default again. To request closing TCP connections with a RESET, specify option --close-with-reset. ** --wsesslog option added to support log-file based session specification (contributed by Dick Carter). ** --period option added to allow a more flexible way to specify session/connection interarrival time. Unlike the --rate argument, this allows deterministic (fixed), uniform, and exponentially distributed interarrival times (contributed by Dick Carter). ** Various bug fixes (see ChangeLog for details). * New in version 0.41: ** In basic statistic, rename "call" to "request". * New in version 0.4: ** Option --http-version can be used to select the HTTP protocol version used in sending requests. 1.0 and 1.0 are the only allowed values for this option at this point. ** What used to be called a "session" is now called a "connection". This reduces confusion between TCP connections and user sessions. ** Stephane's log-file based URL generated has been added. ** The session workload generator now supports the --burst-length parameter to generate bursty session. ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/README ================================================ -*-Mode: outline-*- * Building httperf This release of httperf is using the standard GNU configuration mechanism. The following steps can be used to build it: $ mkdir build $ cd build $ SRCDIR/configure $ make $ make install In this example, SRCDIR refers to the httperf source directory. The last step may have to be executed as "root". To build httperf with debug support turned on, invoke configure with option "--enable-debug". By default, the httperf binary is installed in /usr/local/bin/httperf and the man-page is installed in /usr/local/man/man1/httperf. You can change these defaults by passing appropriate options to the "configure" script. See "configure --help" for details. This release of httperf has preliminary SSL support. To enable it, you need to have OpenSSL (http://www.openssl.org/) already installed on your system. The configure script assumes that the OpenSSH header files and libraries can be found in standard locations (e.g., /usr/include and /usr/lib). If the files are in a different place, you need to tell the configure script where to find them. This can be done by setting environment variables CPPFLAGS and LDFLAGS before invoking "configure". For example, if the SSL header files are installed in /usr/local/ssl/include and the SSL libraries are installed in /usr/local/ssl/lib, then the environment variables should be set like this: CPPFLAGS="-I/usr/local/ssl/include" LDFLAGS="-L/usr/local/ssl/lib" With these settings in place, "configure" can be invoked as usual and SSL should now be found. If SSL has been detected, the following three checks should be answered with "yes": checking for main in -lcrypto... yes checking for SSL_version in -lssl... yes : checking for openssl/ssl.h... yes Note: you may have to delete "config.cache" to ensure that "configure" re-evaluates those checks after changing the settings of the environment variables. WARNING: httperf uses a deterministic seed for the random number generator used by SSL. Thus, the SSL encrypted data is likely to be easy to crack. In other words, do not assume that SSL data transferred when using httperf is (well) encrypted! This release of httperf has been tested under HP-UX 10.20 and 11.0, various versions of Red Hat Linux, both on the x86 and IA-64 architectures. It should be straight-forward to build httperf on other platforms, but your mileage may vary. * Mailing list A mailing list has been set up to encourage discussions among the httperf user community. This list is managed by majordomo. To subscribe to the list, send a mail containing the body: subscribe httperf to majordomo@linux.hpl.hp.com. To post an article to the list, send it directly to httperf@linux.hpl.hp.com. * Running httperf IMPORTANT: It is crucial to run just one copy of httperf per client machine. httperf sucks up all available CPU time on a machine. It is therefore important not to run any other (CPU-intensive) tasks on a client machine while httperf is running. httperf is a CPU hog to ensure that it can generate the desired workload with good accuracy, so do not try to change this without fully understanding what the issues are. ** Examples The simplest way to invoke httperf is with a command line of the form: httperf --server wailua --port 6800 This command results in httperf attempting to make one request for URL http://wailua:6800/. After the reply is received, performance statistics will be printed and the client exits (the statistics are explained below). A list of all available options can be obtained by specifying the --help option (all option names can be abbreviated as long as they remain unambiguous). A more realistic test case might be to issue 1000 HTTP requests at a rate of 10 requests per second. This can be achieved by additionally specifying the --num-conns and --rate options. When specifying the --rate option, it's generally a good idea to also specify a timeout value using the --timeout option. In the example below, a timeout of one second is specified (the ramification of this option will be explained later): httperf --server wailua --port 6800 --num-conns 100 --rate 10 --timeout 1 The performance statistics printed by httperf at the end of the test might look like this: Total: connections 100 requests 100 replies 100 test-duration 9.905 s Connection rate: 10.1 conn/s (99.1 ms/conn, <=1 concurrent connections) Connection time [ms]: min 4.6 avg 5.6 max 19.9 median 4.5 stddev 2.0 Connection time [ms]: connect 1.4 Connection length [replies/conn]: 1.000 Request rate: 10.1 req/s (99.1 ms/req) Request size [B]: 57.0 Reply rate [replies/s]: min 10.0 avg 10.0 max 10.0 stddev 0.0 (1 samples) Reply time [ms]: response 4.1 transfer 0.0 Reply size [B]: header 219.0 content 204.0 footer 0.0 (total 423.0) Reply status: 1xx=0 2xx=100 3xx=0 4xx=0 5xx=0 CPU time [s]: user 2.71 system 7.08 (user 27.4% system 71.5% total 98.8%) Net I/O: 4.7 KB/s (0.0*10^6 bps) Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0 Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0 There are six groups of statistics: overall results ("Total"), connection related results ("Connection"), results relating to the issuing of HTTP requests ("Request"), results relating to the replies received from the server ("Reply"), miscellaneous results relating to the CPU time and network bandwidth used, and, finally, a summary of errors encountered ("Errors"). Let's discuss each in turn: ** "Total" Results The "Total" line summarizes how many TCP connections were initiated by the client, how many requests it sent, how many replies it received, and what the total test duration was. The line below shows that 100 connections were initiated, 100 requests were performed and 100 replies were received. It also shows that total test-duration was 9.905 seconds meaning that the average request rate was almost exactly 10 request per second. Total: connections 100 requests 100 replies 100 test-duration 9.905 s ** "Connection" Results These results convey information related to the TCP connections that are used to communicate with the web server. Specifically, the line below show that new connections were initiated at a rate of 10.1 connections per second. This rate corresponds to a period of 99.1 milliseconds per connection. Finally, the last number shows that at most one connection was open to the server at any given time. Connection rate: 10.1 conn/s (99.1 ms/conn, <=1 concurrent connections) The next line in the output gives lifetime statistics for successful connections. The lifetime of a connection is the time between a TCP connection was initiated and the time the connection was closed. A connection is considered successful if it had at least one request that resulted in a reply from the server. The line shown below indicates that the minimum ("min") connection lifetime was 4.6 milliseconds, the average ("avg") lifetime was 5.6 milliseconds, the maximum ("max") was 19.9 milliseconds, the median ("median") lifetime was 4.5 milliseconds, and that the standard deviation of the lifetimes was 2.0 milliseconds. Connection time [ms]: min 4.6 avg 5.6 max 19.9 median 4.5 stddev 2.0 To compute the median time, httperf collects a histogram of connection lifetimes. The granularity of this histogram is currently 1 milliseconds and the maximum connection lifetime that can be accommodated with the histogram is 100 seconds (these numbers can be changed by editing macros BIN_WIDTH and MAX_LIFETIME in stat/basic.c). This implies that the granularity of the median time is 1 millisecond and that at least 50% of the lifetime samples must have a lifetime of less than 100 seconds. The next statistic in this section is the average time it took to establish a TCP connection to the server (all successful TCP connections establishments are counted, even connections that may have failed eventually). The line below shows that, on average, it took 1.4 milliseconds to establish a connection. Connection time [ms]: connect 1.4 The final line in this section gives the average number of replies that were received per connection. With regular HTTP/1.0, this value is at most 1.0 (when there are no failures), but with HTTP Keep-Alives or HTTP/1.1 persistent connections, this value can be arbitrarily high, indicating that the same connection was used to receive multiple responses. Connection length [replies/conn]: 1.000 ** "Request" Results The first line in the "Request"-related results give the rate at which HTTP requests were issued and the period-length that the rate corresponds to. In the example below, the request rate was 10.1 requests per second, which corresponds to 99.1 milliseconds per request. Request rate: 10.1 req/s (99.1 ms/req) As long as no persistent connections are employed, the "Request" results are typically very similar or identical to the "Connection" results. However, when persistent connections are used, several requests can be issued on a single connection in which case the results would be different. The next line gives the average size of the HTTP request in bytes. In the line show below, the average request size was 57 bytes. Request size [B]: 57.0 ** "Reply" Results For simple measurements, the section with the "Reply" results is probably the most interesting one. The first line gives statistics on the reply rate: Reply rate [replies/s]: min 10.0 avg 10.0 max 10.0 stddev 0.0 (1 samples) The line above indicates that the minimum ("min"), average ("avg"), and maximum ("max") reply rate was ten replies per second. Given these numbers, the standard deviation is, of course, zero. The last number shows that only one reply rate sample was acquired. The present version of httperf collects one rate sample about once every five seconds. To obtain a meaningful standard deviation, it is recommended to run each test long enough so at least thirty samples are obtained---this would correspond to a test duration of at least 150 seconds, or two and a half minutes. The next line gives information on how long it took for the server to respond and how long it took to receive the reply. The line below shows that it took 4.1 milliseconds between sending the first byte of the request and receiving the first byte of the reply. The time to "transfer", or read, the reply was too short to be measured, so it shows up as zero (as we'll see below, the entire reply fit into a single TCP segment and that's why the transfer time was measured as zero). Reply time [ms]: response 4.1 transfer 0.0 Next follow some statistics on the size of the reply---all numbers are reported in bytes. Specifically, the average length of reply headers, the average length of the content, and the average length of reply footers are given (HTTP/1.1 uses footers to realize the "chunked" transfer encoding). For convenience, the average total number of bytes in the replies is also given. In the example below, the average header length ("header") was 219 bytes, the average content length ("content") was 204 bytes, and there were no footers ("footer"), yielding a total reply length of 423 bytes on average. Reply size [B]: header 219.0 content 204.0 footer 0.0 (total 423.0) The final piece in this section is a histogram on the status codes received in the replies. The example below shows that all 100 replies were "successful" replies as they contained a status code of 200 (presumably): Reply status: 1xx=0 2xx=100 3xx=0 4xx=0 5xx=0 ** Miscellaneous Results This section starts with a summary of the CPU time the client consumed. The line below shows that 2.71 seconds were spent executing in user mode ("user"), 7.08 seconds were spent executing in system mode ("system") and that this corresponds to 27.4% user mode execution and 71.5% system execution. The total utilization was almost exactly 100%, which is expected given that httperf is a CPU hog: CPU time [s]: user 2.71 system 7.08 (user 27.4% system 71.5% total 98.8%) Note that any time the total CPU utilization is significantly less than 100%, some other processes must have been running on the client machine while httperf was executing. This makes it likely that the results are "polluted" and the test should be rerun. The next line gives the average network throughput in kilobytes per second (where a kilobyte is 1024 bytes) and in megabits per second (where a megabit is 10^6 bit). The line below shows an average network bandwidth of about 4.7 kilobyte per second. The megabit per second number is zero due to rounding errors. Net I/O: 4.7 KB/s (0.0*10^6 bps) The network bandwidth is computed from the number of bytes sent and received on TCP connections. This means that it accounts for the network payload only (i.e., it doesn't account for protocol headers) and does not take into account retransmissions that may occur at the TCP level. ** "Errors" The final section contains statistics on the errors that occurred during the test. The "total" figure shows the total number of errors that occurred. The two lines below show that in our example run there were no errors: Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0 Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0 The meaning of each error is described below: total: The sum of all following error counts. client-timo: Each time a request is made to the server, a watchdog timer is started. If no (partial) response is received by the time the watchdog timer expires, httperf times out that request a increments this error counter. This is the most common error when driving a server into overload. socket-timo The number of times a TCP connection failed with a socket-level time out (ETIMEDOUT). connrefused The number of times a TCP connection attempt failed with a "connection refused by server" error (ECONNREFUSED). connreset The number of times a TCP connection failed due to a reset (close) by the server. fd-unavail The number of times the httperf client was out of file descriptors. Whenever this count is bigger than zero, the test results are meaning less because the client was overloaded (see discussion on setting --timeout below). addrunavail The number of times the client was out of TCP port numbers (EADDRNOTAVAIL). This error should never occur. If it does, the results should be discarded. ftab-full The number of times the system's file descriptor table was full. Again, this error should never occur. If it does, the results should be discarded. other The number of times other errors occurred. Whenever this occurs, it is necessary to track down the actual error reason. This can be done by compiling httperf with debug support and specifying option --debug 1. ** Selecting appropriate timeout values Since the client machine has only a limited set of resource available, it cannot sustain arbitrarily high HTTP request rates. One limit is that there are only roughly 60,000 TCP port numbers that can be in use at any given time. Since, on HP-UX, it takes one minute for a TCP connection to be fully closed (leave the TIME_WAIT state), the maximum rate a client can sustain is about 1,000 requests per second. The actual sustainable rate is typically lower than this because before running out of TCP ports, a client is likely to run out of file descriptors (one file descriptor is required per open TCP connection). By default, HP-UX 10.20 allows 1024 file descriptors per process. Without a watchdog timer, httperf could potentially quickly use up all available file descriptors, at which point it could not induce any new load on the server (this would primarily happen when the server is overloaded). To avoid this problem, httperf requires that the web server must respond within the time specified by option --timeout. If it does not respond within that time, the client considers the connection to be "dead" and closes it (and increases the "client-timo" error count). The only exception to this rule is that after sending a request, httperf allows the server to take some additional time before it starts responding (to accommodate HTTP requests that take a long time to complete on the server). This additional time is called the "server think time" and can be specified by option --think-timeout. By default, this additional think time is zero, so by default the server has to be able to respond within the time allowed by the --timeout option. In practice, we found that with a --timeout value of 1 second, an HP 9000/735 machine running HP-UX 10.20 can sustain a rate of about 700 connections per second before it starts to run out of file descriptor (the exact rate depends, of course, on a number of factors). To achieve web server loads bigger than that, it is necessary to employ several independent machines, each running one copy of httperf. A timeout of one second effectively means that "slow" connections will typically timeout before TCP even gets a chance to retransmit (the initial retransmission timeout is on the order of 3 seconds). This is usually OK, except that one should keep in mind that it has the effect of truncating the connection life time distribution. ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/README.UW/README.CALL_STATS ================================================ OVERVIEW -------- call_stats is a statistics module in httperf. The purpose of this module is to gather statistics on a per call basis. The statistics reported by the call_stats module can either be filled into a pre-sized buffer or displayed on the fly as the requests are completed. Using a buffer is the recommended means of gathering statistics, due to the reduced overhead during execution. Currently, call_stats can only be used when the workload is generated by the --wsesslog or --uri parameter. Using call_stats in combination with any other workload generation method will produce unknown results. Additionaly, call_stats can not be used in combination with a --wsesslog specifies workload containing bursts. The statistics gathered by the call_stats module are as follows: (1) call number -internal unique identifier -sent as HTTP header to server so that they can be paired (2) connection number -internal unique identifier -sent as HTTP header to server so that they can be paired (3) request size -measured in bytes (4) response size -measured in bytes (5) percentage received (6) byte rate -[ (4) / (8) ] * 8 / 1000000 (7) connection time -measured in seconds -if multiple requests are sent, the first request records the connection time (8) response time -measured in seconds -measured from when the request it sent, to when the last byte is received (9) total time -measured in seconds (10) HTTP status -if the status has been received it will be reported, even if the request times out before all of the data is received (11) time limit -measured in seconds (12) timed out -no => request completed successfully -yes-NC => the request timed out before the connection was established -yes-C => the request timed out after the connection was established (13) file requested -uri requested Some of the statistics reported by the call_stats module rely on knowing the size of the file being requested. If call_stats is used in combination with the --wsesslog parameter, the file sizes are specified in the input log file. If call_stats is used in combination with the --uri parameter, then the --call-stats-file parameter must also be used. IMPLEMENTATION DETAILS ---------------------- There are three points where call_stats gathers information: -when a request is sent -when a request receives the last byte of data -when a connection times out When any of these events occur, the appropriate call_stats function is triggered. If the call_stats module is used with a pre-set buffer, then all of the statistics gathered throughout the execution period are displayed after all of the requests have completed. If the call_stats module is not used with the pre-set buffer then each request's statistics are displayed once it has completed, either by receiving its last byte or by timing out. When a requests completes successfully, all of the statistics are filled in. However, if a request times out, it will only report those statistics that are relevant, depending on what point it timed out at. The challenge comes when a request is scheduled by the workload generator, but never actually gets created. This can occur under the following circumstances: -a request times out before the connection is established -a request times out before all of the requests in a connection are sent In these cases, the call_stats module insures that the unique identifiers for these calls do not get used by other calls, so that it is able to report which calls did not happen. These entries only report statistics (1)-(3), and (11)-(13). ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/README.UW/README.DYNOUT ================================================ The DYNOUT feature allows the timeout to be set separately for each request. It is set by adding a timeout specification after the request filename in the log file, like this example that sets a 10 second timeout: /affinity_set_small4/512KB-54694.txt timeout=10 The normal timeout, specified on the command line, applies to all requests (or maybe sessions). The global value set on the command line will be used if a individual timeout is not set for a request. Code changes required for this feature can be enabled by defining DYNOUT. It is implemented by adding an extra field to the request data structure to record any timeout specific to that request. It requires changes to gen/wsesslog.c to parse and record the timeout values from the wsesslog file. It requires changes to stat/call_stats.c, call.c, and core.c to use the individual timeouts rather than the global session timeout. ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/README.UW/README.NO_RATE_HANG ================================================ The Problem: 1)a connection times out 2)core.c conn_timeout is called by the timer 3)this function signals the EV_CONN_TIMEOUT 4)gen/session conn_timeout is triggered 5)this function calls sess.c sess_failure 6)this function decrements the session object counter 7)there are not longer any ref's for the session 8)this causes event EV_SESS_DESTROYED 9)gen/session sess_destroyed is triggered 10)during clean up of the session it notices the conn 11)the function "helps" by calling core_close on the conn 12)A new connection is created in the place of the old one (httperf recycles space) 13)now return to core.c conn_timeout 14)call core_close on the conn, notice that this is the new connection 15)core_close destroys both the timer and frees the socket 16)left sitting waiting for an event that will never happen Sample: stszepes@scsltxxx:~/httperf-timout/build$ ./httperf --port=6800 --wsesslog=3,0,test5.log --call-stats=3 --timeout=0.0001 --print-request --print-reply --client=3/4 httperf: Collecting call stats buffer size = 3 httperf --print-reply --print-request --timeout=0.0001 --client=3/4 --server=localhost --port=6800 --uri=/ --send-buffer=4096 --recv-buffer=16384 --call-stats=3 --call-stats-file= --wsesslog=3,0.000,test5.log Run on hostname: scsltxxx Run at: Tue Jun 15 16:08:54 2010 Effective CPU mask: 0x3 hash_enter: localhost 6800 stat basic init: using maximum errno = 500 httperf main perf_sample timer_schedule timer_SCHEDULE called, delay = 5.000000 conn id = 0, core_connect interested_in_writing conn id = 0, interested_in_writing conn id = 0, core_connect timer_schedule timer_SCHEDULE called, delay = 0.000100 conn id = 0, core_loop_handle_socket timer_cancel timer_CANCEL called conn id = 0, core_send interested_in_writing conn id = 0, interested_in_writing conn id = 0, schedule_timeouts timer_schedule timer_SCHEDULE called, delay = 0.000100 conn id = 0, core_loop_handle_socket timer_cancel timer_CANCEL called SH0:GET /docs/1B.txt HTTP/1.1 SH0:User-Agent: httperf/0.8.4 SH0:Host: localhost SH0:Client-Id: 3 0 SH0: SS0: header 89 content 0 conn id = 0, do_send interested_in_reading conn id = 0, interested_in_reading conn id = 0, schedule_timeouts timer_schedule timer_SCHEDULE called, delay = 0.000100 conn id = 0, conn_timeout *******timeout occurs******* x value = 0 conn id = 0, conn_timeout EV_CONN_TIMEOUT x value = 0, timed_out = 0 conn id = 0, sess_destroyed core_close *******sess_destroyed being "helpfull"******* conn id = 0, core_close... conn id = 0, core_close executing... conn id = 1, core_connect interested_in_writing *******new connection created******* conn id = 1, interested_in_writing conn id = 1, core_connect timer_schedule timer_SCHEDULE called, delay = 0.000100 conn id = 1, conn_timeout core_close x value = 0, timed_out = 0 *******closing the new connection(cont. on next line)******* conn id = 1, core_close... *******x value should match the conn id and timed_out should be 1 if this was the correct conn******* conn id = 1, core_close executing... conn id = 1, core_close timer_cancel timer_CANCEL called *******now the timer and the listening conn are gone******* perf_sample timer_schedule timer_SCHEDULE called, delay = 5.000000 perf_sample timer_schedule timer_SCHEDULE called, delay = 5.000000 perf_sample timer_schedule timer_SCHEDULE called, delay = 5.000000 ... *******this will continue untill interupted******* Maximum connect burst length: 1 Total: connections 2 requests 1 replies 0 test-duration 15.651 s Number of connected connections is currently = 0 Connection rate: 0.1 conn/s (7825.5 ms/conn, <=1 concurrent connections) Connected connection rate: 0.1 conn/s (7825.5 ms/conn, <=1 concurrent connected connections) Connection time [ms]: min 0.0 avg 0.0 max 0.0 median 0.0 stddev 0.0 Connection time [ms]: connect 0.2 Connection length [replies/conn]: 0.000 Response time (no timeouts) [ms]: nan Response time (only timeouts) [ms]: inf Response time (all) [ms]: inf Request rate: 0.1 req/s (15651.0 ms/req) Request size [B]: 89.0 Overall reply rate: 0.0 replies/sec Reply rate [replies/s]: min 0.0 avg 0.0 max 0.0 stddev 0.0 (3 samples) Reply time [ms]: response 0.0 transfer 0.0 Reply size [B]: header 0.0 content 0.0 footer 0.0 (total 0.0) Reply status: 1xx=0 2xx=0 3xx=0 4xx=0 5xx=0 CPU time [s]: user 11.44 system 4.20 (user 73.1% system 26.9% total 100.0%) Net I/O: 0.0 KB/s (0.0*10^6 bps) Errors: total 1 client-timo 1 socket-timo 0 connrefused 0 connreset 0 Errors: fd-unavail 0 addrunavail 0 ftab-full 0 addrinuse 0 other 0 Unconnected timeouts 0 connected timeouts 1 total (1) client_timeouts 1 Call Statistics: call number conn number request size response size % bytes recvd byte rate conn time response time total time HTTP status time limit timed out file requested (bytes) (bytes) (Mbps) (s) (s) (s) (s) 0 0 1 0 0.00 0.0 0.0002260 0.0018110 0.0020370 0 0.0001000 yes-C /docs/1B.txt 1 0 -1 0 -0.00 nan 0.0000000 0.0000000 0.0000000 0 0.0000000 NA -- Session rate [sess/s]: min 0.00 avg 0.00 max 0.00 stddev 0.00 (0/1) Session: avg 0.00 connections/session Session lifetime [s]: 0.0 Session failtime [s]: 0.0 Session length histogram: 1 Solutions: Two (easy) ways: 1)stop the sess_destroyed function from being so "helpfull" -if a rate has not been specified by the user, don't make the call to core_close 2)recognize that the sess_destroyed function has already done the work -when core.c conn_timeout is called store a local copy of the conn id -before calling the core_close function make sure they match Suggestion: Use solution 2 -it is very simple -solution 1 is more of a bandaid >it is not clear if this will actually solve the underlying problem >it may have unknow affects -beyond this problem solution 2 it is a good thing >should be sure what you are operating on is what you think it is ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/README.UW/README.STABLE_STATS ================================================ The STABLE_STATS feature defines a ramp-up and ramp-down time for an experiment. Sessions that start before the ramp-up period expires are not counted in the statistics, and sessions that start within the ramp-down time at the end of the experiment are also not counted. The ramp-up and ramp-down periods are specified using --ramp-up-num-conns and --ramp-down-num-conns, and these parameters are specified as numbers of connections. Each session uses a single connection, so when sessions are in use, the number of connections is equal to the number of sessions. This feature is can be enabled by defining STABLE_STATS. Because STABLE_STATS adds some values to the param struct, it needs to be defined everywhere param is used; so I define STABLE_STATS in the configure file rather than Makefile.in. This is likely not the right way to do this. It is implemented mostly in stat/basic.c. It is controlled by two variables stable_conns_start and stable_conns_end that are set to the values supplied on the command line, or to default values that will select all connections. Each connection is given an id number in sequence. If the connection id is larger than stable_conns_start and smaller than stable_conns_end, then an 'is_stable' flag is set true for that connection, otherwise it is set false. The code is modified to keep two versions of the most important statistics; one set that includes only connections that are stable, and the other that collects statistics for all connections. To avoid changing the data scripts that extract information from the output, the stable stats values are reported using the existing labels and the statistics for all connections are reported using new labels that start with "All". ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/README.UW/README.STAGGER_START ================================================ The --stagger-start option causes httperf to start multiple httperf clients at slightly different times to avoid burstiness in the requests. Without this option, if all instances of httperf start at approximately the same time, they will issue requests at the same time. With these synchronized requests, the traffic consists of large bursts of requests that cause an unrealistic load on the test server. The session period is divided by the number of clients, and each client delays for a different fraction of the session period before starting the first session, based on client ID. This will have the effect of staggering the requests from the different clients rather than synchronizing them. This option has the greatest effect when using a uniform rate. If a rate distribution is used, the staggering won't make much of a difference. This modification is not surrounded by an #ifdef since it is simple and has no effect if the option is not selected. It is implemented by modifying the rate_generator_start() function in gen/rate.c. If param.client.stagger_start is set, this routine adds a small delay to the deadline for when the first session should start. Subsequent arrival delays are calculated relative to the first in tick(), so with deterministic arrival rates, the clients will continue to issue requests in a staggered fashion throughout the experiment. ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/README.UW/README.TIMEOUT ================================================ High Level Overview: Notation: T is the value --timeout=T A connection must be established in T seconds or the client will timeout Once a connection is established, the client must send the request within T seconds or the client will timeout Once the request is sent the response must be completely received within T seconds or the client will timeout Note: The concept of a session is only used by HTTPERF in the context of generating a workload specified by wsess or wsesslog. The core of HTTPERF, which is responsible for establishing connections and sending requests to the server, is not aware of the concept of a session. As such, there are no timers that span the length of a session. Lower Level Details: Timer started when: (1)establishing a connection (time = T) (2)when a call is moved to the sendq (time = T) (3)another spot in do_send...* (4)when a call is moved to the recvq (time = T) (5)after some data has been recved but not all (time = R) R is the time remaining on the prevous timer started at (4) or (5) Timer cancelled when (if a timer exists): -core_close: -a connection fails -a connection times out -a call finishs -a session finishs -core_loop_handle_socket: -when a connection is established -when the request is sent -when data is recved Observations: -timers are created a minimum of 3 times for a connection (assuming 1 call per conn) >twice before sending the request [timer start: (1), (2)] >once after sending and before receiving any data [timer start: (4)] >larger file requests create more timers then small file requests #"extra" timers are created during the receiving process #the delay they are created with is determined by the calls timeout time** #timer start: (5) Aside: -wsesslog uses timers to create user think time -the rate generator uses timers >it allows them to time out (ie they are not cancelled) -in httperf.c there are two timers that are/can be created >perf_sample >dump_stats * -I believe this is used when the request is large but I am not sure I have not run any tests that have caused this to occur ** -the timeout time is first set at the time when the call is moved to the sendq It is reset before all other timers are created with the exception of this one -the delay the timer is created with can be a negative number which means the timer is created with the default value of 1 'tick' (which is the smallest it can be given) This means that a call can go passed its timeout time as long data continues to be received in 1 tick intervals -I do not know what 1 'tick' is in terms of time in seconds ######################################################### static void schedule_timeouts (Conn *s) --------------------------------------------------------- { Any_Type arg; Time timeout = 0.0; /* if there is already a timer running for this connection * then do not add a new one */ if (s->watchdog) return; /* take the shortest timeout between the first item in the sendq * and the first item in the recvq */ if (s->sendq) timeout = s->sendq->timeout; if (s->recvq && (timeout == 0.0 || timeout > s->recvq->timeout)) timeout = s->recvq->timeout; if (timeout > 0.0) { arg.vp = s; s->watchdog = timer_schedule (conn_timeout, arg,timeout - timer_now ()); /* timer starts: (2), (4), (5) */ } } ######################################################### ######################################################### int core_connect (Conn *s) --------------------------------------------------------- SYSCALL (CONNECT,result = connect (sd, sin, sizeof (*sin))); saved_err = errno; if (result == 0) { #ifdef HAVE_SSL if (param.use_ssl) { core_ssl_connect (s); } else #endif { s->state = S_CONNECTED; arg.l = 0; event_signal (EV_CONN_CONNECTED, (Object *) s, arg); } } else if (errno == EINPROGRESS) { /* The socket becomes writable only after the connection has been established. Hence we wait for writability to detect connection establishment. */ s->state = S_CONNECTING; interested_in_writing (s); /* it is neccisary to 'manually' add this timer because there is * no calls in the sendq or recvq, whose timeouts would have been used * in the call to interested_in_writing() */ if (param.timeout > 0.0) { arg.vp = s; assert (!s->watchdog); s->watchdog = timer_schedule (conn_timeout, arg, param.timeout); /* timer start: (1) */ } } else { len = sizeof (async_errno); if (getsockopt (sd, SOL_SOCKET, SO_ERROR, &async_errno, &len) ==0 && async_errno != 0) { errno = async_errno; } saved_err = async_errno; ######################################################### ######################################################### static void interested_in_reading (Conn *s) --------------------------------------------------------- { set_active (s, &rdfds); #ifdef HAVE_EPOLL if (param.use_epoll) update_epoll_event (s); #endif schedule_timeouts (s); /* timer start: (4), (5) */ } ######################################################### ######################################################### static void interested_in_writing (Conn *s) --------------------------------------------------------- { set_active(s, &wrfds); #ifdef HAVE_EPOLL if (param.use_epoll) update_epoll_event (s); #endif schedule_timeouts (s); /* timer start: (2) */ } ######################################################### ######################################################### static void core_loop_handle_socket (int sd, int is_readable, int is_writable) --------------------------------------------------------- if (conn->watchdog) { timer_cancel (conn->watchdog); conn->watchdog = 0; } if (conn->state == S_CONNECTING) { #ifdef HAVE_SSL if (param.use_ssl) core_ssl_connect (conn); else #endif { if (is_writable) { len = sizeof (async_errno); rc = getsockopt (sd, SOL_SOCKET, SO_ERROR, &async_errno, &len); if (rc < 0) { printf("%s: getsockopt failed\n", __FUNCTION__); perror(__FUNCTION__); exit(1); } else if (async_errno == 0) { FD_CLR (sd, &wrfds); conn->state = S_CONNECTED; arg.l = 0; event_signal (EV_CONN_CONNECTED, (Object *) conn, arg); } else { // printf("%s: connect failed %s\n", __FUNCTION__, strerror(async_errno)); conn_failure(conn, async_errno); } } } } else { if (is_writable && conn->sendq) do_send (conn); if (is_readable && conn->recvq) do_recv (conn); } ######################################################### ######################################################### called by: conn_failure conn_timeout session_destroyed (gen/session.c) call_done (gen/session.c) void core_close (Conn *conn) --------------------------------------------------------- if (conn->watchdog) { timer_cancel (conn->watchdog); conn->watchdog = 0; } ######################################################### ######################################################### static void do_send (Conn *conn) --------------------------------------------------------- if (call->req.iov_index < NELEMS (call->req.iov)) { /* there are more header bytes to write */ call->timeout = param.timeout ? timer_now () + param.timeout : 0.0; interested_in_writing (conn); /* timer start: (3) */ return; } /* we're done with sending this request */ conn->sendq = call->sendq_next; if (!conn->sendq) { conn->sendq_tail = 0; FD_CLR (sd, &wrfds); } arg.l = 0; event_signal (EV_CALL_SEND_STOP, (Object *) call, arg); if (conn->state >= S_CLOSING) { call_dec_ref (call); return; } /* get ready to receive matching reply (note that we implicitly pass on the reference to the call from the sendq to the recvq): */ call->recvq_next = 0; if (!conn->recvq) conn->recvq = conn->recvq_tail = call; else { conn->recvq_tail->recvq_next = call; conn->recvq_tail = call; } call->timeout = param.timeout + param.think_timeout; if (call->timeout > 0.0) call->timeout += timer_now (); interested_in_reading (conn); /* timer start: (4) */ if (conn->state < S_REPLY_STATUS) conn->state = S_REPLY_STATUS; /* expecting reply status */ if (!conn->sendq) return; arg.l = 0; event_signal (EV_CALL_SEND_START, (Object *) conn->sendq, arg); if (conn->state >= S_CLOSING) return; } } ######################################################### ######################################################### static void do_recv (Conn *s) --------------------------------------------------------- /* if there is more information expected then was received in the buffer then a timer is created */ if (s->recvq) interested_in_reading (c->conn); /* timer start: (5) */ } ######################################################### ######################################################### called by: -send_calls (gen/session.c) int core_send (Conn *conn, Call *call) --------------------------------------------------------- /* insert call into connection's send queue: */ call_inc_ref (call); call->sendq_next = 0; if (!conn->sendq) { conn->sendq = conn->sendq_tail = call; arg.l = 0; event_signal (EV_CALL_SEND_START, (Object *) call, arg); if (conn->state >= S_CLOSING) return -1; call->timeout = param.timeout ? timer_now () + param.timeout : 0.0; interested_in_writing (conn); /* timer start: (2) */ } else { conn->sendq_tail->sendq_next = call; conn->sendq_tail = call; } ######################################################### ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/README.UW/README.WSESSLOG ================================================ The log file specified by the --wsesslog option is used to generate the workload created by httperf. This log file consists of a set of sessions, where a session is a set of requests sent to a web server. The connection settings for the web server is set by the command line options --server, --port and --ssl. In order to allow individual sessions to use different connection settings (for example some sessions use ssl and others don't), the ability to specify these settings for individual sessions has been added. If the log file does not specify the connection settings, the command line options are used as a default. To specify connections settings for an individual session in the wsesslog file, an additional line must be added, before the set of requests. This line is structered as follows: session [port=X] [server=Y] [ssl=Z] /uri /uri ... The individual parameters can be listed in any order, however the first item must be the word 'session' followed by whitespace. Additionaly, none of the parameters are manditory. In order to allow the call_stats statistics module to work with a wsesslog specified workload, a new request parameter was added to specify the size of the request. If this parameter is not set then the call_stats module has no way of knowing the size of the request, and will assign it a value of -2. The following is an example of a log file that can be used with the call_stats module, which includes some sample uses of session specific connection settings: session ssl=off server=localhost port=6800 /docs/10K.txt size=10240 /docs/100K.txt size=102400 /docs/10K.txt size=10240 /docs/100K.txt size=102400 session ssl=on port=6444 server=129.97.169.14 /docs/10B.txt size=10 /docs/1M.txt size=1048576 /docs/1K.txt size=1024 /docs/10K.txt size=10240 session ssl=off port=6801 /docs/10K.txt size=10240 /docs/100K.txt size=102400 /docs/10K.txt size=10240 /docs/100K.txt size=102400 session ssl=on port=6443 server=localhost /docs/10B.txt size=10 /docs/1M.txt size=1048576 /docs/1K.txt size=1024 /docs/10K.txt size=10240 ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/README.UW/man-call_stats.txt ================================================ Examples of httperf used with call stats: httperf --port=6800 --num-calls=4 --num-conns=2 --uri=/docs/10K.txt --call-stats=6 --call-stats-file=call_stats.in --timeout=1 This will track the first 6 of 8 calls (2 connections, each with 4 calls) made to the server, using call_stats.in to determine the size(s) of the file(s) requested. httperf --port=6800 --wsesslog=3,0,input.log --call-stats=0 --timeout=1 This will use the input.log file to generate the workload and print the statistics for each call as it is completed. The call stats options are used as follows: --call-stats=X This will cause httperf to track statistics for the first X calls made to the server, where X>0. If X=0 then statistics will be printed on the fly, as the calls complete. This option needs to be used in combination with --call-stats-file or --wsesslog so that the proper file size can be determined. If a file is requested, who's size has not been specified, it will be assigned a size of -2 bytes so that it can be easily identified. --call-stats-file=S This will inform httperf to use the file S to determine the sizes of the files requested from the server The first line of the file S must be a number N, which indicates the number of (URI, file size) mappings. The next N lines consist of a URI and an integer seperated by a single space. The integer is the size of the file in bytes. A sample call-stats-file is as follows: 13 /docs/1B.txt 1 /docs/2B.txt 2 /docs/10B.txt 10 /docs/960B.txt 960 /docs/14900B.txt 14900 /docs/1K.txt 1024 /docs/2K.txt 2048 /docs/3K.txt 3072 /docs/4K.txt 4096 /docs/5K.txt 5120 /docs/10K.txt 10240 /docs/100K.txt 102400 /docs/1M.txt 1048576 Sample output: $ httperf --port=6800 --num-calls=4 --num-conns=2 --uri=/docs/10K.txt --call-stats=6 --call-stats-file=call_stats.in --timeout=1 httperf: Collecting call stats buffer size = 6 httperf: file sizes from = call_stats.in httperf --timeout=1 --client=0/1 --server=localhost --port=6800 --uri=/docs/10K.txt --send-buffer=4096 --recv-buffer=16384 --call-stats=6 --call-stats-file=call_stats.in --num-conns=2 --num-calls=4 Run on hostname: scsltxxx Run at: Wed Aug 11 10:29:47 2010 Effective CPU mask: 0x3 hash_enter: localhost 6800 stat basic init: using maximum errno = 500 Maximum connect burst length: 1 Total: connections 2 requests 8 replies 8 test-duration 1.100 s Number of connected connections is currently = 0 Connection rate: 1.8 conn/s (550.1 ms/conn, <=1 concurrent connections) Connected connection rate: 1.8 conn/s (550.1 ms/conn, <=1 concurrent connected connections) Connection time [ms]: min 382.9 avg 550.1 max 717.2 median 382.5 stddev 236.4 Connection time [ms]: connect 0.5 Connection length [replies/conn]: 4.000 Response time (no timeouts) [ms]: 137.5 Response time (only timeouts) [ms]: nan Response time (all) [ms]: 137.5 Request rate: 7.3 req/s (137.5 ms/req) Request size [B]: 74.0 Overall reply rate: 7.3 replies/sec Reply rate [replies/s]: min 0.0 avg 0.0 max 0.0 stddev 0.0 (0 samples) Reply time [ms]: response 18.7 transfer 118.7 Reply size [B]: header 71.0 content 10240.0 footer 0.0 (total 10311.0) Reply status: 1xx=0 2xx=8 3xx=0 4xx=0 5xx=0 CPU time [s]: user 0.86 system 0.20 (user 77.8% system 18.2% total 96.0%) Net I/O: 73.7 KB/s (0.6*10^6 bps) Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0 Errors: fd-unavail 0 addrunavail 0 ftab-full 0 addrinuse 0 other 0 Unconnected timeouts 0 connected timeouts 0 total (0) client_timeouts 0 Call Statistics (buffer filled): call number conn number request size response size % bytes recvd byte rate conn time response time total time HTTP status time limit timed out file requested (bytes) (bytes) (Mbps) (s) (s) (s) (s) 0 0 10240 10240 100.00 1.6 0.0001609 0.0499520 0.0501130 200 1.0000000 no /docs/10K.txt 1 0 10240 10240 100.00 2.5 0.0000000 0.0331109 0.0331109 200 1.0000000 no /docs/10K.txt 2 0 10240 10240 100.00 0.8 0.0000000 0.0980442 0.0980442 200 1.0000000 no /docs/10K.txt 3 0 10240 10240 100.00 0.4 0.0000000 0.2016768 0.2016768 200 1.0000000 no /docs/10K.txt 4 1 10240 10240 100.00 0.4 0.0008731 0.2034709 0.2043440 200 1.0000000 no /docs/10K.txt 5 1 10240 10240 100.00 0.4 0.0000000 0.1899390 0.1899390 200 1.0000000 no /docs/10K.txt ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/README.WINDOWS ================================================ Thu Apr 17 12:12:51 2003 Tim Brecht I was able to produce a version of httperf that looks like it can be run on Windows machines. I've compiled it on a cygwin environment but have been able to run a few simple tests in a non cygwin environment (Windows 2000 and Windows 98). ---------------------------------------------------------------------- NOTES: ------ It seems that with the Nagle algorithm disabled that httperf.exe sends a separate packet for each element of a writev vector. Httperf uses several vectors for each request. This can lead to significant performance hits for both the client and the server. E.g., the request arrives in something like 5-7 packets and depending on how the server is implemented it may require that many reads to get one request from the socket. I've only experimented a bit with leaving the Nagle algorithm enabled. This reduces the number of packets needed for a request (still > 1) but I haven't checked on timing/delays. ---------------------------------------------------------------------- INCREASING THE NUMBER OF FDS: ----------------------------- Cygwin seems to be set up to handle a user defined FD_SETSIZE. So to increase the number of open file descriptors (default is 64) with CYGWIN. in "config.h" #define FD_SETSIZE (1024) ---------------------------------------------------------------------- RUNNING: -------- After producing a statically compiled version of the httperf executable (httperf.exe) I copied it and the CYGWIN DLL (cygwin1.dll) to another machine (both in the same directory) and was able to run a few simple tests. The file cygwin1.dll can be found in a cygwin installation in the /bin directory. ---------------------------------------------------------------------- COMPILING: --------- Compiling httperf my version of cygwin, which was running on Windows 2000. % mkdir build % cd build % ../configure Then I modified config.h so that a few things that autoconf defined were not defined. /* Define if you have the header file. */ /* #define HAVE_OPENSSL_SSL_H 1 */ /* Define if you have the crypto library (-lcrypto). */ /* #define HAVE_LIBCRYPTO 1 */ I modified the Makefile to remove # LIBS = -lcrypto -lm LIBS = -lm From the build directory I modified all the Makefiles so that everything is statically linked. % vi Makefile */Makefile # LDFLAGS = LDFLAGS = -static -Bstatic ---------------------------------------------------------------------- ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/TBB-NEW ================================================ Working on code Adam did for handling headers (including range requests). Think about making this code selectable via --with or --without options. Added stuff to use an increased number of open files. The "include" directory has new definitions for __FD_SETSIZE. This is used in the Makefile.in where -DBIG_FD_SETSIZE is set. ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/TODO ================================================ Wed Oct 17 10:15:25 EDT 2012 UW - Long term: add ability to specify start_conn_num and end_conn_num for stable stats (so this works without wsesslog). - Test compiled and ./httperf MAC OS X Linux Ubuntu 12.04 Linux (old Redhat version on rocket) ../configure ../configure --enable-debug - Clean up lots of warnings and at some point turn on -Wall -Werror - Talk to Tyler about what the code is doing that generates these warnings and clean up that code. ../../stat/call_stats.c:315: warning: operation on 'i' may be undefined - Need man page info for --calls-stats - Need man page info for --ramp-up-num-conns - Need man page info for --ramp-down-num-conns - Need man page info for --stagger-start - Need man page info for --spec-stats - *** Check if SSL/HTTPS can be specified in wsesslog and if it works - check fpsetmask(0) on FreeBSD - Modify Makefile.in to do the right stuff - Possibly Makefile.uwinc - Test the SSL case - Is HAVE_SCHED_AFFINITY off by default (it should be) - Integrate _HAVE_EPOLL HASVE_SCHED_AFFINITY, etc. into configure - Cleanup #ifdef OLDWAY ---------------------------------------------------------------------- Some ideas (contributions/patches welcome): - wsesspage: don't fetch same object more than once (assume the existence of a cache)---this avoids trouble with recursive pages - make httperf easier to use; some ideas: o Make httperf into a network daemon that is controlled by an httperf frontend. This would allow running tests with a single command line even when multiple clients are involved. The performance results should be reported both on a per-client basis and in a summarized form reporting overall server behavior. o Provide (default) scripts to run certain benchmarks. o Provide (default) scripts to produce performance graphs. - use cycle registers to get time on CPUs that have such registers (IA-64, PA-RISC, x86, Alpha, at least) - randomize the uri's generated by --wset so we can defeat file prefetching that the server (or the server's OS) may attempt to do Done: + Specifying --session-cookie without specifying a session workload causes httperf to core-dump (reported by Dick Carter, 10/13/98) + elevate `Session' to same level as Call and Connection + sample session throughput when using sessions (not just rate throughput) + integrate Dick's wsesslog + write man-page + chunked replies fail after the first reply (at least on HP-UX) + core.c does not fully support pipelined requests yet; would require changes to the watchdog management ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/aclocal.m4 ================================================ AC_DEFUN(AC_TYPE_LONG_LONG, [AC_CACHE_CHECK(for long long type, ac_cv_type_long_long, [AC_TRY_COMPILE(, [unsigned long long x, y, z; x = y/z], ac_cv_type_long_long=yes, ac_cv_type_long_long=no)]) if test $ac_cv_type_long_long = yes; then AC_DEFINE(u_wide,unsigned long long) else AC_DEFINE(u_wide,unsigned long) fi ]) ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/bt2line ================================================ #!/bin/bash if [ $# -ne 1 ] ; then echo "Usage: $0 executable" exit fi executable=$1 while read line ; do addr=$(echo $line | grep -o '\[.*\]' | grep -o '[abcdefx0-9]*') if [ -n "$addr" ] ; then src=$(addr2line -e $executable $addr) echo $line | sed "s|\[\(.*\)\]|\[$src\]|" else echo $line fi done ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/call.c ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include static u_long next_id = 0; int inc_call_next_id(int n) { next_id = n+next_id; return next_id - n; } int get_call_next_id () { return (int) next_id; } void call_init (Call *c) { # define DEFAULT_METHOD "GET" c->id = next_id++; call_set_method (c, DEFAULT_METHOD, sizeof (DEFAULT_METHOD) - 1); c->req.version = param.http_version; c->req.iov[IE_BLANK].iov_base = (caddr_t) " "; c->req.iov[IE_BLANK].iov_len = 1; c->req.iov[IE_NEWLINE1].iov_base = (caddr_t) "\r\n"; c->req.iov[IE_NEWLINE1].iov_len = 2; c->req.iov[IE_NEWLINE2].iov_base = (caddr_t) "\r\n"; c->req.iov[IE_NEWLINE2].iov_len = 2; c->file_size = -2; c->record_conn_time = 0; #ifdef UW_DYNOUT c->timelimit = param.timeout; #endif /* UW_DYNOUT */ } void call_deinit (Call *call) { } int call_append_request_header (Call *c, const char *hdr, size_t len) { u_int num_hdrs = c->req.num_extra_hdrs; if (num_hdrs >= MAX_EXTRA_HEADERS) { fprintf (stderr, "%s.call_append_request_header: max headers " "(%d) exceeded.\n", prog_name, MAX_EXTRA_HEADERS); return -1; } c->req.iov[IE_FIRST_HEADER + num_hdrs].iov_base = (caddr_t) hdr; c->req.iov[IE_FIRST_HEADER + num_hdrs].iov_len = len; c->req.num_extra_hdrs = num_hdrs + 1; return 0; } ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/call.h ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef call_h #define call_h #include #include #include #include #include /* Max. # of additional request header lines we allow: */ #define MAX_EXTRA_HEADERS 4 typedef enum IOV_Element { IE_METHOD, IE_BLANK, /* space separating method from location */ IE_LOC, /* for proxy requests only */ IE_URI, IE_PROTL, IE_HOST, /* for the "Host:" header */ IE_NEWLINE1, IE_FIRST_HEADER, IE_LAST_HEADER = IE_FIRST_HEADER + MAX_EXTRA_HEADERS - 1, IE_NEWLINE2, IE_CONTENT, IE_LEN /* must be last */ } IOV_Element; /* I call this a "call" because "transaction" is too long and because it's basically a remote procedure call consisting of a request that is answered by a reply. */ typedef struct Call { Object obj; u_long id; /* unique id */ /* Connection this call is being sent on. This pointer is NOT reference counted as otherwise we would get a recursive dependency between connections and calls.... */ struct Conn *conn; struct Call *sendq_next; struct Call *recvq_next; Time timeout; /* used for watchdog management */ #ifdef UW_DYNOUT Time timelimit; #endif /* UW_DYNOUT */ struct { Time time_send_start; Time time_recv_start; } basic; /* this is used by call stats */ int file_size; int record_conn_time; char id_hdr[28]; /* the request: */ struct { int version; /* 0x10000*major + minor */ u_int num_extra_hdrs; /* number of additional headers in use */ int iov_index; /* first iov element that has data */ size_t size; /* # of bytes sent */ struct iovec iov_saved; /* saved copy of iov[iov_index] */ struct iovec iov[IE_LEN]; } req; /* the reply: */ struct { int status; int version; /* 0x10000*major + minor */ size_t header_bytes; /* # of header bytes received so far */ size_t content_bytes; /* # of reply data bytes received so far */ size_t footer_bytes; /* # of footer bytes received so far */ char * content; /* Used for reply-verification only */ } reply; } Call; /* Initialize the new call object C. */ extern void call_init (Call *c); /* Destroy the call-specific state in call object C. */ extern void call_deinit (Call *c); /* increment the next_id counter * this is used by call_stats*/ extern int inc_call_next_id(int n); /*get the current next_id value */ extern int get_call_next_id(); #define call_new() ((Call *) object_new (OBJ_CALL)) #define call_inc_ref(c) object_inc_ref ((Object *) (c)) #define call_dec_ref(c) object_dec_ref ((Object *) (c)) /* Append the additional request header line(s) HDR to the request headers. The total length of the additional headers is LEN bytes. The headers must be end with a carriage-return, line-feed sequence ("\r\n"). */ extern int call_append_request_header (Call *c, const char *hdr, size_t len); #define call_set_version(c, ver) (c)->req.version = (ver); #define call_set_method(c, method, method_len) \ do \ { \ c->req.iov[IE_METHOD].iov_base = (caddr_t) method; \ c->req.iov[IE_METHOD].iov_len = method_len; \ } \ while (0) #define call_set_location(c, loc, loc_len) \ do \ { \ c->req.iov[IE_LOC].iov_base = (caddr_t) loc; \ c->req.iov[IE_LOC].iov_len = loc_len; \ } \ while (0) #define call_set_uri(c, uri, uri_len) \ do \ { \ c->req.iov[IE_URI].iov_base = (caddr_t) uri; \ c->req.iov[IE_URI].iov_len = uri_len; \ } \ while (0) #define call_set_contents(c, content, content_len) \ do \ { \ c->req.iov[IE_CONTENT].iov_base = (caddr_t) content; \ c->req.iov[IE_CONTENT].iov_len = content_len; \ } \ while (0) #endif /* call_h */ ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/config.cache ================================================ # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs. It is not useful on other systems. # If it contains results you don't want to keep, you may remove or edit it. # # By default, configure uses ./config.cache as the cache file, # creating it if it does not exist already. You can give configure # the --cache-file=FILE option to use a different cache file; that is # what configure does when it calls configure scripts in # subdirectories, so they share the cache. # Giving --cache-file=/dev/null disables caching, for debugging configure. # config.status only pays attention to the cache file if you give it the # --recheck option to rerun configure. # ac_cv_c_const=${ac_cv_c_const='yes'} ac_cv_func_alloca_works=${ac_cv_func_alloca_works='yes'} ac_cv_func_getopt_long=${ac_cv_func_getopt_long='yes'} ac_cv_func_getpagesize=${ac_cv_func_getpagesize='yes'} ac_cv_func_gettimeofday=${ac_cv_func_gettimeofday='yes'} ac_cv_func_mmap_fixed_mapped=${ac_cv_func_mmap_fixed_mapped='yes'} ac_cv_func_select=${ac_cv_func_select='yes'} ac_cv_func_socket=${ac_cv_func_socket='yes'} ac_cv_func_strdup=${ac_cv_func_strdup='yes'} ac_cv_func_strerror=${ac_cv_func_strerror='yes'} ac_cv_func_strtod=${ac_cv_func_strtod='yes'} ac_cv_func_strtol=${ac_cv_func_strtol='yes'} ac_cv_func_strtoul=${ac_cv_func_strtoul='yes'} ac_cv_func_vprintf=${ac_cv_func_vprintf='yes'} ac_cv_header_alloca_h=${ac_cv_header_alloca_h='yes'} ac_cv_header_fcntl_h=${ac_cv_header_fcntl_h='yes'} ac_cv_header_openssl_ssl_h=${ac_cv_header_openssl_ssl_h='yes'} ac_cv_header_stdc=${ac_cv_header_stdc='yes'} ac_cv_header_sys_ioctl_h=${ac_cv_header_sys_ioctl_h='yes'} ac_cv_header_sys_time_h=${ac_cv_header_sys_time_h='yes'} ac_cv_header_time=${ac_cv_header_time='yes'} ac_cv_header_unistd_h=${ac_cv_header_unistd_h='yes'} ac_cv_lib_crypto_main=${ac_cv_lib_crypto_main='yes'} ac_cv_lib_m_main=${ac_cv_lib_m_main='yes'} ac_cv_lib_ssl_SSL_version=${ac_cv_lib_ssl_SSL_version='yes'} ac_cv_path_install=${ac_cv_path_install='/usr/bin/install -c'} ac_cv_prog_CC=${ac_cv_prog_CC='gcc'} ac_cv_prog_CPP=${ac_cv_prog_CPP='gcc -E'} ac_cv_prog_RANLIB=${ac_cv_prog_RANLIB='ranlib'} ac_cv_prog_cc_cross=${ac_cv_prog_cc_cross='no'} ac_cv_prog_cc_g=${ac_cv_prog_cc_g='yes'} ac_cv_prog_cc_works=${ac_cv_prog_cc_works='yes'} ac_cv_prog_gcc=${ac_cv_prog_gcc='yes'} ac_cv_prog_gcc_traditional=${ac_cv_prog_gcc_traditional='no'} ac_cv_prog_make_make_set=${ac_cv_prog_make_make_set='yes'} ac_cv_sizeof_long=${ac_cv_sizeof_long='8'} ac_cv_type_long_long=${ac_cv_type_long_long='yes'} ac_cv_type_signal=${ac_cv_type_signal='void'} ac_cv_type_size_t=${ac_cv_type_size_t='yes'} ac_cv_type_u_char=${ac_cv_type_u_char='yes'} ac_cv_type_u_int=${ac_cv_type_u_int='yes'} ac_cv_type_u_long=${ac_cv_type_u_long='yes'} ac_cv_type_u_short=${ac_cv_type_u_short='yes'} ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/config.guess ================================================ #! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 # Free Software Foundation, Inc. version='2000-09-05' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Written by Per Bothner . # Please send patches to . # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you # don't specify an explicit system type (host/target name). # # Only a few systems have been added to this list; please add others # (but try to keep the structure clean). # me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of this system. Operation modes: -h, --help print this help, then exit -V, --version print version number, then exit" help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case "$1" in --version | --vers* | -V ) echo "$version" ; exit 0 ;; --help | --h* | -h ) echo "$usage"; exit 0 ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) exec >&2 echo "$me: invalid option $1" echo "$help" exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi # Use $HOST_CC if defined. $CC may point to a cross-compiler if test x"$CC_FOR_BUILD" = x; then if test x"$HOST_CC" != x; then CC_FOR_BUILD="$HOST_CC" else if test x"$CC" != x; then CC_FOR_BUILD="$CC" else CC_FOR_BUILD=cc fi fi fi # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 8/24/94.) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown dummy=dummy-$$ trap 'rm -f $dummy.c $dummy.o $dummy; exit 1' 1 2 15 # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # Netbsd (nbsd) targets should (where applicable) match one or # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # Determine the machine/vendor (is the vendor relevant). case "${UNAME_MACHINE}" in amiga) machine=m68k-unknown ;; arm32) machine=arm-unknown ;; atari*) machine=m68k-atari ;; sun3*) machine=m68k-sun ;; mac68k) machine=m68k-apple ;; macppc) machine=powerpc-apple ;; hp3[0-9][05]) machine=m68k-hp ;; ibmrt|romp-ibm) machine=romp-ibm ;; *) machine=${UNAME_MACHINE}-unknown ;; esac # The Operating System including object format. if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep __ELF__ >/dev/null then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi # The OS release release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit 0 ;; alpha:OSF1:*:*) if test $UNAME_RELEASE = "V4.0"; then UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` fi # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. cat <$dummy.s .data \$Lformat: .byte 37,100,45,37,120,10,0 # "%d-%x\n" .text .globl main .align 4 .ent main main: .frame \$30,16,\$26,0 ldgp \$29,0(\$27) .prologue 1 .long 0x47e03d80 # implver \$0 lda \$2,-1 .long 0x47e20c21 # amask \$2,\$1 lda \$16,\$Lformat mov \$0,\$17 not \$1,\$18 jsr \$26,printf ldgp \$29,0(\$26) mov 0,\$16 jsr \$26,exit .end main EOF $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null if test "$?" = 0 ; then case `./$dummy` in 0-0) UNAME_MACHINE="alpha" ;; 1-0) UNAME_MACHINE="alphaev5" ;; 1-1) UNAME_MACHINE="alphaev56" ;; 1-101) UNAME_MACHINE="alphapca56" ;; 2-303) UNAME_MACHINE="alphaev6" ;; 2-307) UNAME_MACHINE="alphaev67" ;; esac fi rm -f $dummy.s $dummy echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit 0 ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit 0 ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit 0 ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit 0;; amiga:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit 0 ;; arc64:OpenBSD:*:*) echo mips64el-unknown-openbsd${UNAME_RELEASE} exit 0 ;; arc:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; hkmips:OpenBSD:*:*) echo mips-unknown-openbsd${UNAME_RELEASE} exit 0 ;; pmax:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; sgi:OpenBSD:*:*) echo mips-unknown-openbsd${UNAME_RELEASE} exit 0 ;; wgrisc:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; *:OS/390:*:*) echo i370-ibm-openedition exit 0 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit 0;; SR2?01:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit 0;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit 0 ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit 0 ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; i86pc:SunOS:5.*:*) echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit 0 ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit 0 ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit 0 ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit 0 ;; atari*:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit 0 ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit 0 ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit 0 ;; sun3*:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mac68k:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvme68k:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvme88k:OpenBSD:*:*) echo m88k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit 0 ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit 0 ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit 0 ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit 0 ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit 0 ;; mips:*:*:UMIPS | mips:*:*:RISCos) sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD $dummy.c -o $dummy \ && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ && rm $dummy.c $dummy && exit 0 rm -f $dummy.c $dummy echo mips-mips-riscos${UNAME_RELEASE} exit 0 ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit 0 ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit 0 ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit 0 ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit 0 ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit 0 ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit 0 ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit 0 ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit 0 ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit 0 ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit 0 ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i?86:AIX:*:*) echo i386-ibm-aix exit 0 ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 rm -f $dummy.c $dummy echo rs6000-ibm-aix3.2.5 elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit 0 ;; *:AIX:*:4) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'` if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=4.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit 0 ;; *:AIX:*:*) echo rs6000-ibm-aix exit 0 ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit 0 ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit 0 ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit 0 ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit 0 ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit 0 ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit 0 ;; 9000/[34678]??:HP-UX:*:*) case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy` rm -f $dummy.c $dummy esac HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit 0 ;; 3050*:HI-UX:*:*) sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 rm -f $dummy.c $dummy echo unknown-hitachi-hiuxwe2 exit 0 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit 0 ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit 0 ;; *9??*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit 0 ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit 0 ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit 0 ;; i?86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit 0 ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit 0 ;; hppa*:OpenBSD:*:*) echo hppa-unknown-openbsd exit 0 ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit 0 ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit 0 ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit 0 ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit 0 ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit 0 ;; CRAY*X-MP:*:*:*) echo xmp-cray-unicos exit 0 ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} exit 0 ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ exit 0 ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*T3E:*:*:*) echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY-2:*:*:*) echo cray2-cray-unicos exit 0 ;; F300:UNIX_System_V:*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit 0 ;; F301:UNIX_System_V:*:*) echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'` exit 0 ;; hp300:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; i?86:BSD/386:*:* | i?86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit 0 ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit 0 ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit 0 ;; *:FreeBSD:*:*) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit 0 ;; *:OpenBSD:*:*) echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` exit 0 ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit 0 ;; i*:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit 0 ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit 0 ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i386-pc-interix exit 0 ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit 0 ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit 0 ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; *:GNU:*:*) echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit 0 ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit 0 ;; *:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent # problems with other programs or directories called `ld' in the path. ld_help_string=`cd /; ld --help 2>&1` ld_supported_emulations=`echo $ld_help_string \ | sed -ne '/supported emulations:/!d s/[ ][ ]*/ /g s/.*supported emulations: *// s/ .*// p'` case "$ld_supported_emulations" in *ia64) echo "${UNAME_MACHINE}-unknown-linux" exit 0 ;; i?86linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" exit 0 ;; elf_i?86) TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" ;; i?86coff) echo "${UNAME_MACHINE}-pc-linux-gnucoff" exit 0 ;; sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" exit 0 ;; armlinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" exit 0 ;; elf32arm*) echo "${UNAME_MACHINE}-unknown-linux-gnuoldld" exit 0 ;; armelf_linux*) echo "${UNAME_MACHINE}-unknown-linux-gnu" exit 0 ;; m68klinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" exit 0 ;; elf32ppc | elf32ppclinux) # Determine Lib Version cat >$dummy.c < #if defined(__GLIBC__) extern char __libc_version[]; extern char __libc_release[]; #endif main(argc, argv) int argc; char *argv[]; { #if defined(__GLIBC__) printf("%s %s\n", __libc_version, __libc_release); #else printf("unkown\n"); #endif return 0; } EOF LIBC="" $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null if test "$?" = 0 ; then ./$dummy | grep 1\.99 > /dev/null if test "$?" = 0 ; then LIBC="libc1" fi fi rm -f $dummy.c $dummy echo powerpc-unknown-linux-gnu${LIBC} exit 0 ;; shelf_linux) echo "${UNAME_MACHINE}-unknown-linux-gnu" exit 0 ;; esac if test "${UNAME_MACHINE}" = "alpha" ; then cat <$dummy.s .data \$Lformat: .byte 37,100,45,37,120,10,0 # "%d-%x\n" .text .globl main .align 4 .ent main main: .frame \$30,16,\$26,0 ldgp \$29,0(\$27) .prologue 1 .long 0x47e03d80 # implver \$0 lda \$2,-1 .long 0x47e20c21 # amask \$2,\$1 lda \$16,\$Lformat mov \$0,\$17 not \$1,\$18 jsr \$26,printf ldgp \$29,0(\$26) mov 0,\$16 jsr \$26,exit .end main EOF LIBC="" $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null if test "$?" = 0 ; then case `./$dummy` in 0-0) UNAME_MACHINE="alpha" ;; 1-0) UNAME_MACHINE="alphaev5" ;; 1-1) UNAME_MACHINE="alphaev56" ;; 1-101) UNAME_MACHINE="alphapca56" ;; 2-303) UNAME_MACHINE="alphaev6" ;; 2-307) UNAME_MACHINE="alphaev67" ;; esac objdump --private-headers $dummy | \ grep ld.so.1 > /dev/null if test "$?" = 0 ; then LIBC="libc1" fi fi rm -f $dummy.s $dummy echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0 elif test "${UNAME_MACHINE}" = "mips" ; then cat >$dummy.c < /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #ifdef __MIPSEB__ printf ("%s-unknown-linux-gnu\n", argv[1]); #endif #ifdef __MIPSEL__ printf ("%sel-unknown-linux-gnu\n", argv[1]); #endif return 0; } EOF $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 rm -f $dummy.c $dummy elif test "${UNAME_MACHINE}" = "s390"; then echo s390-ibm-linux && exit 0 elif test "${UNAME_MACHINE}" = "x86_64"; then echo x86_64-unknown-linux-gnu && exit 0 else # Either a pre-BFD a.out linker (linux-gnuoldld) # or one that does not give us useful --help. # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout. # If ld does not provide *any* "supported emulations:" # that means it is gnuoldld. echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:" test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 case "${UNAME_MACHINE}" in i?86) VENDOR=pc; ;; *) VENDOR=unknown; ;; esac # Determine whether the default compiler is a.out or elf cat >$dummy.c < #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 printf ("%s-${VENDOR}-linux-gnu\n", argv[1]); # else printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); # endif # else printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); # endif #else printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]); #endif return 0; } EOF $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 rm -f $dummy.c $dummy test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 fi ;; # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions # are messed up and put the nodename in both sysname and nodename. i?86:DYNIX/ptx:4*:*) echo i386-sequent-sysv4 exit 0 ;; i?86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit 0 ;; i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit 0 ;; i?86:*:5:7*) # Fixed at (any) Pentium or better UNAME_MACHINE=i586 if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} fi exit 0 ;; i?86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit 0 ;; i?86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit 0 ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i386. echo i386-pc-msdosdjgpp exit 0 ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit 0 ;; paragon:*:*:*) echo i860-intel-osf1 exit 0 ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit 0 ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit 0 ;; M68*:*:R3V[567]*:*) test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4.3${OS_REL} && exit 0 /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4 && exit 0 ;; m68*:LynxOS:2.*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit 0 ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit 0 ;; i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit 0 ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit 0 ;; rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit 0 ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit 0 ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit 0 ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit 0 ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit 0 ;; PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit 0 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit 0 ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit 0 ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit 0 ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit 0 ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit 0 ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit 0 ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit 0 ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit 0 ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit 0 ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit 0 ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit 0 ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit 0 ;; *:Darwin:*:*) echo `uname -p`-apple-darwin${UNAME_RELEASE} exit 0 ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) if test "${UNAME_MACHINE}" = "x86pc"; then UNAME_MACHINE=pc fi echo `uname -p`-${UNAME_MACHINE}-nto-qnx exit 0 ;; *:QNX:*:4*) echo i386-pc-qnx exit 0 ;; NSR-[KW]:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit 0 ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit 0 ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit 0 ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit 0 ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) #if !defined (ultrix) printf ("vax-dec-bsd\n"); exit (0); #else printf ("vax-dec-ultrix\n"); exit (0); #endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0 rm -f $dummy.c $dummy # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit 0 ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit 0 ;; c34*) echo c34-convex-bsd exit 0 ;; c38*) echo c38-convex-bsd exit 0 ;; c4*) echo c4-convex-bsd exit 0 ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess version = $version uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "version='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/config.h ================================================ /* config.h. Generated automatically by configure. */ /* config.h.in. Generated automatically from configure.in by autoheader. */ /* Define if using alloca.c. */ /* #undef C_ALLOCA */ /* Define to empty if the keyword does not work. */ /* #undef const */ /* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. This function is required for alloca.c support on those systems. */ /* #undef CRAY_STACKSEG_END */ /* Define if you have alloca, as a function or macro. */ #define HAVE_ALLOCA 1 /* Define if you have and it should be used (not on Ultrix). */ #define HAVE_ALLOCA_H 1 /* Define if you don't have vprintf but do have _doprnt. */ /* #undef HAVE_DOPRNT */ /* Define if you have a working `mmap' system call. */ #define HAVE_MMAP 1 /* Define if you have the vprintf function. */ #define HAVE_VPRINTF 1 /* Define as the return type of signal handlers (int or void). */ #define RETSIGTYPE void /* Define to `unsigned' if doesn't define. */ /* #undef size_t */ /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at run-time. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ /* #undef STACK_DIRECTION */ /* Define if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Define if you can safely include both and . */ #define TIME_WITH_SYS_TIME 1 /* Define if you have the getpagesize function. */ #define HAVE_GETPAGESIZE 1 /* Define if you have the gettimeofday function. */ #define HAVE_GETTIMEOFDAY 1 /* Define if you have the select function. */ #define HAVE_SELECT 1 /* Define if you have the socket function. */ #define HAVE_SOCKET 1 /* Define if you have the strdup function. */ #define HAVE_STRDUP 1 /* Define if you have the strerror function. */ #define HAVE_STRERROR 1 /* Define if you have the strtod function. */ #define HAVE_STRTOD 1 /* Define if you have the strtol function. */ #define HAVE_STRTOL 1 /* Define if you have the strtoul function. */ #define HAVE_STRTOUL 1 /* Define if you have the header file. */ #define HAVE_FCNTL_H 1 /* Define if you have the header file. */ #define HAVE_OPENSSL_SSL_H 1 /* Define if you have the header file. */ #define HAVE_SYS_IOCTL_H 1 /* Define if you have the header file. */ #define HAVE_SYS_TIME_H 1 /* Define if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define if you have the crypto library (-lcrypto). */ #define HAVE_LIBCRYPTO 1 /* Define if you have the m library (-lm). */ #define HAVE_LIBM 1 /* Define if you have the ssl library (-lssl). */ #define HAVE_LIBSSL 1 /* Define if you have Open SSL (header files, libssl.a, libcrypto.a). */ #define HAVE_SSL 1 /* Define to the size of a long (in bytes). */ #define SIZEOF_LONG 8 /* Define to `unsigned char' if doesn't define. */ /* #undef u_char */ /* Define to `unsigned short' if doesn't define. */ /* #undef u_short */ /* Define to `unsigned int' if doesn't define. */ /* #undef u_int */ /* Define to `unsigned long' if doesn't define. */ /* #undef u_long */ /* Define to widest `unsigned' integer type available. */ #define u_wide unsigned long long ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/config.h.in ================================================ /* config.h.in. Generated automatically from configure.in by autoheader. */ /* Define if using alloca.c. */ #undef C_ALLOCA /* Define to empty if the keyword does not work. */ #undef const /* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. This function is required for alloca.c support on those systems. */ #undef CRAY_STACKSEG_END /* Define if you have alloca, as a function or macro. */ #undef HAVE_ALLOCA /* Define if you have and it should be used (not on Ultrix). */ #undef HAVE_ALLOCA_H /* Define if you don't have vprintf but do have _doprnt. */ #undef HAVE_DOPRNT /* Define if you have a working `mmap' system call. */ #undef HAVE_MMAP /* Define if you have the vprintf function. */ #undef HAVE_VPRINTF /* Define as the return type of signal handlers (int or void). */ #undef RETSIGTYPE /* Define to `unsigned' if doesn't define. */ #undef size_t /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at run-time. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ #undef STACK_DIRECTION /* Define if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define if you can safely include both and . */ #undef TIME_WITH_SYS_TIME /* Define if you have the getpagesize function. */ #undef HAVE_GETPAGESIZE /* Define if you have the gettimeofday function. */ #undef HAVE_GETTIMEOFDAY /* Define if you have the select function. */ #undef HAVE_SELECT /* Define if you have the socket function. */ #undef HAVE_SOCKET /* Define if you have the strdup function. */ #undef HAVE_STRDUP /* Define if you have the strerror function. */ #undef HAVE_STRERROR /* Define if you have the strtod function. */ #undef HAVE_STRTOD /* Define if you have the strtol function. */ #undef HAVE_STRTOL /* Define if you have the strtoul function. */ #undef HAVE_STRTOUL /* Define if you have the header file. */ #undef HAVE_FCNTL_H /* Define if you have the header file. */ #undef HAVE_OPENSSL_SSL_H /* Define if you have the header file. */ #undef HAVE_SYS_IOCTL_H /* Define if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define if you have the header file. */ #undef HAVE_UNISTD_H /* Define if you have the crypto library (-lcrypto). */ #undef HAVE_LIBCRYPTO /* Define if you have the m library (-lm). */ #undef HAVE_LIBM /* Define if you have the ssl library (-lssl). */ #undef HAVE_LIBSSL /* Define if you have Open SSL (header files, libssl.a, libcrypto.a). */ #undef HAVE_SSL /* Define to the size of a long (in bytes). */ #undef SIZEOF_LONG /* Define to `unsigned char' if doesn't define. */ #undef u_char /* Define to `unsigned short' if doesn't define. */ #undef u_short /* Define to `unsigned int' if doesn't define. */ #undef u_int /* Define to `unsigned long' if doesn't define. */ #undef u_long /* Define to widest `unsigned' integer type available. */ #undef u_wide ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/config.log ================================================ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. configure:548: checking for gcc configure:661: checking whether the C compiler (gcc ) works configure:677: gcc -o conftest -DNDEBUG -D_GNU_SOURCE -D_XOPEN_SOURCE conftest.c 1>&5 configure:703: checking whether the C compiler (gcc ) is a cross-compiler configure:708: checking whether we are using GNU C configure:736: checking whether gcc accepts -g configure:798: checking for a BSD compatible install configure:851: checking whether make sets ${MAKE} configure:880: checking for ranlib configure:908: checking how to run the C preprocessor configure:989: checking whether gcc needs -traditional configure:1062: checking host system type configure:1083: checking target system type configure:1101: checking build system type configure:1140: checking for main in -lm configure:1183: checking for main in -lcrypto configure:1226: checking for SSL_version in -lssl configure:1275: checking for ANSI C header files configure:1382: checking for fcntl.h configure:1382: checking for sys/ioctl.h configure:1382: checking for sys/time.h configure:1382: checking for unistd.h configure:1382: checking for openssl/ssl.h configure:1429: checking for working const configure:1504: checking for size_t configure:1537: checking for long long type configure:1575: checking whether time.h and sys/time.h may both be included configure:1610: checking size of long configure:1649: checking for u_char configure:1682: checking for u_short configure:1715: checking for u_int configure:1748: checking for u_long configure:1784: checking for working alloca.h configure:1817: checking for alloca configure:2019: checking for unistd.h configure:2058: checking for getpagesize configure:2111: checking for working mmap configure:2282: checking return type of signal handlers configure:2323: checking for vprintf configure:2431: checking for gettimeofday configure:2431: checking for select configure:2431: checking for socket configure:2431: checking for strdup configure:2431: checking for strerror configure:2431: checking for strtod configure:2431: checking for strtol configure:2431: checking for strtoul configure:2431: checking for getopt_long ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/config.status ================================================ #! /bin/sh # Generated automatically by configure. # Run this file to recreate the current configuration. # This directory was configured as follows, # on host shocktop: # # ./configure # # Compiler output produced by configure, useful for debugging # configure, is in ./config.log if it exists. ac_cs_usage="Usage: ./config.status [--recheck] [--version] [--help]" for ac_option do case "$ac_option" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) echo "running ${CONFIG_SHELL-/bin/sh} ./configure --no-create --no-recursion" exec ${CONFIG_SHELL-/bin/sh} ./configure --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) echo "./config.status generated by autoconf version 2.13" exit 0 ;; -help | --help | --hel | --he | --h) echo "$ac_cs_usage"; exit 0 ;; *) echo "$ac_cs_usage"; exit 1 ;; esac done ac_given_srcdir=. ac_given_INSTALL="/usr/bin/install -c" trap 'rm -fr stat/Makefile lib/Makefile Makefile gen/Makefile config.h conftest*; exit 1' 1 2 15 # Protect against being on the right side of a sed subst in config.status. sed 's/%@/@@/; s/@%/@@/; s/%g$/@g/; /@g$/s/[\\&%]/\\&/g; s/@@/%@/; s/@@/@%/; s/@g$/%g/' > conftest.subs <<\CEOF /^[ ]*VPATH[ ]*=[^:]*$/d s%@SHELL@%/bin/sh%g s%@CFLAGS@%-g -O2 -Wall %g s%@CPPFLAGS@% -DNDEBUG -D_GNU_SOURCE -D_XOPEN_SOURCE%g s%@CXXFLAGS@%%g s%@FFLAGS@%%g s%@DEFS@%-DHAVE_CONFIG_H%g s%@LDFLAGS@%%g s%@LIBS@%-lssl -lcrypto -lm %g s%@exec_prefix@%${prefix}%g s%@prefix@%/usr/local%g s%@program_transform_name@%s,x,x,%g s%@bindir@%${exec_prefix}/bin%g s%@sbindir@%${exec_prefix}/sbin%g s%@libexecdir@%${exec_prefix}/libexec%g s%@datadir@%${prefix}/share%g s%@sysconfdir@%${prefix}/etc%g s%@sharedstatedir@%${prefix}/com%g s%@localstatedir@%${prefix}/var%g s%@libdir@%${exec_prefix}/lib%g s%@includedir@%${prefix}/include%g s%@oldincludedir@%/usr/include%g s%@infodir@%${prefix}/info%g s%@mandir@%${prefix}/man%g s%@CC@%gcc%g s%@INSTALL_PROGRAM@%${INSTALL}%g s%@INSTALL_SCRIPT@%${INSTALL_PROGRAM}%g s%@INSTALL_DATA@%${INSTALL} -m 644%g s%@SET_MAKE@%%g s%@RANLIB@%ranlib%g s%@CPP@%gcc -E%g s%@host@%x86_64-unknown-linux-gnu%g s%@host_alias@%x86_64-unknown-linux-gnu%g s%@host_cpu@%x86_64%g s%@host_vendor@%unknown%g s%@host_os@%linux-gnu%g s%@target@%x86_64-unknown-linux-gnu%g s%@target_alias@%x86_64-unknown-linux-gnu%g s%@target_cpu@%x86_64%g s%@target_vendor@%unknown%g s%@target_os@%linux-gnu%g s%@build@%x86_64-unknown-linux-gnu%g s%@build_alias@%x86_64-unknown-linux-gnu%g s%@build_cpu@%x86_64%g s%@build_vendor@%unknown%g s%@build_os@%linux-gnu%g s%@ALLOCA@%%g CEOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. ac_file=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_cmds # Line after last line for current file. ac_more_lines=: ac_sed_cmds="" while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file else sed "${ac_end}q" conftest.subs > conftest.s$ac_file fi if test ! -s conftest.s$ac_file; then ac_more_lines=false rm -f conftest.s$ac_file else if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f conftest.s$ac_file" else ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" fi ac_file=`expr $ac_file + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_cmds` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi CONFIG_FILES=${CONFIG_FILES-"stat/Makefile lib/Makefile Makefile gen/Makefile"} for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" # A "../" for each directory in $ac_dir_suffix. ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` else ac_dir_suffix= ac_dots= fi case "$ac_given_srcdir" in .) srcdir=. if test -z "$ac_dots"; then top_srcdir=. else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; *) # Relative path. srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" top_srcdir="$ac_dots$ac_given_srcdir" ;; esac case "$ac_given_INSTALL" in [/$]*) INSTALL="$ac_given_INSTALL" ;; *) INSTALL="$ac_dots$ac_given_INSTALL" ;; esac echo creating "$ac_file" rm -f "$ac_file" configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." case "$ac_file" in *Makefile*) ac_comsub="1i\\ # $configure_input" ;; *) ac_comsub= ;; esac ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` sed -e "$ac_comsub s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g s%@top_srcdir@%$top_srcdir%g s%@INSTALL@%$INSTALL%g " $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file fi; done rm -f conftest.s* # These sed commands are passed to sed as "A NAME B NAME C VALUE D", where # NAME is the cpp macro being defined and VALUE is the value it is being given. # # ac_d sets the value in "#define NAME VALUE" lines. ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' ac_dC='\3' ac_dD='%g' # ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_uB='\([ ]\)%\1#\2define\3' ac_uC=' ' ac_uD='\4%g' # ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_eB='$%\1#\2define\3' ac_eC=' ' ac_eD='%g' if test "${CONFIG_HEADERS+set}" != set; then CONFIG_HEADERS="config.h" fi for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac echo creating $ac_file rm -f conftest.frag conftest.in conftest.out ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` cat $ac_file_inputs > conftest.in cat > conftest.frag < conftest.out rm -f conftest.in mv conftest.out conftest.in cat > conftest.frag < conftest.out rm -f conftest.in mv conftest.out conftest.in cat > conftest.frag < conftest.out rm -f conftest.in mv conftest.out conftest.in cat > conftest.frag < conftest.out rm -f conftest.in mv conftest.out conftest.in cat > conftest.frag < conftest.out rm -f conftest.in mv conftest.out conftest.in cat > conftest.frag < conftest.out rm -f conftest.in mv conftest.out conftest.in cat > conftest.frag < conftest.out rm -f conftest.in mv conftest.out conftest.in cat > conftest.frag < conftest.out rm -f conftest.in mv conftest.out conftest.in rm -f conftest.frag conftest.h echo "/* $ac_file. Generated automatically by configure. */" > conftest.h cat conftest.in >> conftest.h rm -f conftest.in if cmp -s $ac_file conftest.h 2>/dev/null; then echo "$ac_file is unchanged" rm -f conftest.h else # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" fi rm -f $ac_file mv conftest.h $ac_file fi fi; done exit 0 ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/config.sub ================================================ #! /bin/sh # Configuration validation subroutine script, version 1.1. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 # Free Software Foundation, Inc. version='2000-09-11' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -V, --version print version number, then exit" help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case "$1" in --version | --vers* | -V ) echo "$version" ; exit 0 ;; --help | --h* | -h ) echo "$usage"; exit 0 ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) exec >&2 echo "$me: invalid option $1" echo "$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit 0;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis) os= basic_machine=$1 ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \ | arme[lb] | armv[2345] | armv[345][lb] | pyramid | mn10200 | mn10300 | tron | a29k \ | 580 | i960 | h8300 \ | x86 | ppcbe | mipsbe | mipsle | shbe | shle | armbe | armle \ | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \ | hppa64 \ | alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \ | alphaev6[78] \ | we32k | ns16k | clipper | i370 | sh | sh[34] \ | powerpc | powerpcle \ | 1750a | dsp16xx | pdp11 | mips16 | mips64 | mipsel | mips64el \ | mips64orion | mips64orionel | mipstx39 | mipstx39el \ | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \ | mips64vr5000 | miprs64vr5000el | mcore \ | sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \ | thumb | d10v | d30v | fr30 | avr) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65 | pj | pjl) ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i[234567]86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. # FIXME: clean up the formatting here. vax-* | tahoe-* | i[234567]86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \ | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \ | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \ | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \ | xmp-* | ymp-* \ | x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* | armbe-* | armle-* \ | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \ | hppa2.0n-* | hppa64-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \ | alphaev6[78]-* \ | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \ | clipper-* | orion-* \ | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \ | sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \ | mips64el-* | mips64orion-* | mips64orionel-* \ | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \ | mipstx39-* | mipstx39el-* | mcore-* \ | f301-* | armv*-* | s390-* | sv1-* | t3e-* \ | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \ | thumb-* | v850-* | d30v-* | tic30-* | c30-* | fr30-* \ | bs2000-* | tic54x-* | c54x-* | x86_64-*) ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | ymp) basic_machine=ymp-cray os=-unicos ;; cray2) basic_machine=cray2-cray os=-unicos ;; [ctj]90-cray) basic_machine=c90-cray os=-unicos ;; crds | unos) basic_machine=m68k-crds ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i[34567]86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i[34567]86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i[34567]86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i[34567]86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; i386-go32 | go32) basic_machine=i386-unknown os=-go32 ;; i386-mingw32 | mingw32) basic_machine=i386-unknown os=-mingw32 ;; i[34567]86-pw32 | pw32) basic_machine=i586-unknown os=-pw32 ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mipsel*-linux*) basic_machine=mipsel-unknown os=-linux-gnu ;; mips*-linux*) basic_machine=mips-unknown os=-linux-gnu ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; mmix*) basic_machine=mmix-knuth os=-mmixware ;; monitor) basic_machine=m68k-rom68k os=-coff ;; msdos) basic_machine=i386-unknown os=-msdos ;; mvs) basic_machine=i370-ibm os=-mvs ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; np1) basic_machine=np1-gould ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pentium | p5 | k5 | k6 | nexen) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon) basic_machine=i686-pc ;; pentiumii | pentium2) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexen-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=rs6000-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sparclite-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=t3e-cray os=-unicos ;; tic54x | c54x*) basic_machine=tic54x-unknown os=-coff ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; tower | tower-32) basic_machine=m68k-ncr ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xmp) basic_machine=xmp-cray os=-unicos ;; xps | xps100) basic_machine=xps100-honeywell ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; mips) if [ x$os = x-linux-gnu ]; then basic_machine=mips-unknown else basic_machine=mips-mips fi ;; romp) basic_machine=romp-ibm ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh3 | sh4) base_machine=sh-unknown ;; sparc | sparcv9) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; c4x*) basic_machine=c4x-none os=-coff ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i[34567]86-*) ;; *) os=-nto$os ;; esac ;; -nto*) os=-nto-qnx ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -*MiNT) os=-mint ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-ibm) os=-aix ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f301-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -ptx*) vendor=sequent ;; -vxsim* | -vxworks*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -*MiNT) vendor=atari ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "version='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/configure ================================================ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated automatically using autoconf version 2.13 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. # Defaults: ac_help= ac_default_prefix=/usr/local # Any additions from configure.in: ac_help="$ac_help --enable-debug enable debug support" # Initialize some variables set by options. # The variables have the same names as the options, with # dashes changed to underlines. build=NONE cache_file=./config.cache exec_prefix=NONE host=NONE no_create= nonopt=NONE no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= target=NONE verbose= x_includes=NONE x_libraries=NONE bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' # Initialize some other variables. subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. ac_max_here_lines=12 ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi case "$ac_option" in -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) ac_optarg= ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case "$ac_option" in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir="$ac_optarg" ;; -build | --build | --buil | --bui | --bu) ac_prev=build ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build="$ac_optarg" ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file="$ac_optarg" ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir="$ac_optarg" ;; -disable-* | --disable-*) ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` eval "enable_${ac_feature}=no" ;; -enable-* | --enable-*) ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "enable_${ac_feature}='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix="$ac_optarg" ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he) # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat << EOF Usage: configure [options] [host] Options: [defaults in brackets after descriptions] Configuration: --cache-file=FILE cache test results in FILE --help print this message --no-create do not create output files --quiet, --silent do not print \`checking...' messages --version print the version of autoconf that created configure Directory and file names: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [same as prefix] --bindir=DIR user executables in DIR [EPREFIX/bin] --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] --libexecdir=DIR program executables in DIR [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data in DIR [PREFIX/share] --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data in DIR [PREFIX/com] --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] --libdir=DIR object code libraries in DIR [EPREFIX/lib] --includedir=DIR C header files in DIR [PREFIX/include] --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] --infodir=DIR info documentation in DIR [PREFIX/info] --mandir=DIR man documentation in DIR [PREFIX/man] --srcdir=DIR find the sources in DIR [configure dir or ..] --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names EOF cat << EOF Host type: --build=BUILD configure for building on BUILD [BUILD=HOST] --host=HOST configure for HOST [guessed] --target=TARGET configure for TARGET [TARGET=HOST] Features and packages: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR EOF if test -n "$ac_help"; then echo "--enable and --with options recognized:$ac_help" fi exit 0 ;; -host | --host | --hos | --ho) ac_prev=host ;; -host=* | --host=* | --hos=* | --ho=*) host="$ac_optarg" ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir="$ac_optarg" ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir="$ac_optarg" ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir="$ac_optarg" ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir="$ac_optarg" ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir="$ac_optarg" ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir="$ac_optarg" ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir="$ac_optarg" ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix="$ac_optarg" ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix="$ac_optarg" ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix="$ac_optarg" ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name="$ac_optarg" ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir="$ac_optarg" ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir="$ac_optarg" ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site="$ac_optarg" ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir="$ac_optarg" ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir="$ac_optarg" ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target="$ac_optarg" ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers) echo "configure generated by autoconf version 2.13" exit 0 ;; -with-* | --with-*) ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "with_${ac_package}='$ac_optarg'" ;; -without-* | --without-*) ac_package=`echo $ac_option|sed -e 's/-*without-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` eval "with_${ac_package}=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes="$ac_optarg" ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries="$ac_optarg" ;; -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } ;; *) if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then echo "configure: warning: $ac_option: invalid host type" 1>&2 fi if test "x$nonopt" != xNONE; then { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } fi nonopt="$ac_option" ;; esac done if test -n "$ac_prev"; then { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } fi trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 # File descriptor usage: # 0 standard input # 1 file creation # 2 errors and warnings # 3 some systems may open it to /dev/tty # 4 used on the Kubota Titan # 6 checking for... messages and results # 5 compiler messages saved in config.log if test "$silent" = yes; then exec 6>/dev/null else exec 6>&1 fi exec 5>./config.log echo "\ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. " 1>&5 # Strip out --no-create and --no-recursion so they do not pile up. # Also quote any args containing shell metacharacters. ac_configure_args= for ac_arg do case "$ac_arg" in -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) ac_configure_args="$ac_configure_args '$ac_arg'" ;; *) ac_configure_args="$ac_configure_args $ac_arg" ;; esac done # NLS nuisances. # Only set these to C if already set. These must not be set unconditionally # because not all systems understand e.g. LANG=C (notably SCO). # Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! # Non-C LC_CTYPE values break the ctype check. if test "${LANG+set}" = set; then LANG=C; export LANG; fi if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo > confdefs.h # A filename unique to this package, relative to the directory that # configure is in, which we can look for to find out if srcdir is correct. ac_unique_file=timer.h # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_prog=$0 ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } else { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } fi fi srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then echo "loading site script $ac_site_file" . "$ac_site_file" fi done if test -r "$cache_file"; then echo "loading cache $cache_file" . $cache_file else echo "creating cache $cache_file" > $cache_file fi ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross ac_exeext= ac_objext=o if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then ac_n= ac_c=' ' ac_t=' ' else ac_n=-n ac_c= ac_t= fi else ac_n= ac_c='\c' ac_t= fi # Check whether --enable-debug or --disable-debug was given. if test "${enable_debug+set}" = set; then enableval="$enable_debug" : fi if test "$enable_debug" = yes; then CPPFLAGS="${CPPFLAGS} -DDEBUG" else CPPFLAGS="${CPPFLAGS} -DNDEBUG" fi CPPFLAGS="${CPPFLAGS} -D_GNU_SOURCE -D_XOPEN_SOURCE" LDFLAGS="${LDFLAGS}" # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:548: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="gcc" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:578: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_prog_rejected=no ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" break fi done IFS="$ac_save_ifs" if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# -gt 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift set dummy "$ac_dir/$ac_word" "$@" shift ac_cv_prog_CC="$@" fi fi fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then case "`uname -s`" in *win32* | *WIN32*) # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:629: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="cl" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi ;; esac fi test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 echo "configure:661: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF #line 672 "configure" #include "confdefs.h" main(){return(0);} EOF if { (eval echo configure:677: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then ac_cv_prog_cc_cross=no else ac_cv_prog_cc_cross=yes fi else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 ac_cv_prog_cc_works=no fi rm -fr conftest* ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 echo "configure:703: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 echo "configure:708: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no fi fi echo "$ac_t""$ac_cv_prog_gcc" 1>&6 if test $ac_cv_prog_gcc = yes; then GCC=yes else GCC= fi ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 echo "configure:736: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo 'void f(){}' > conftest.c if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then ac_cv_prog_cc_g=yes else ac_cv_prog_cc_g=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 if test "$ac_test_CFLAGS" = set; then CFLAGS="$ac_save_CFLAGS" elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi ac_aux_dir= for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do if test -f $ac_dir/install-sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f $ac_dir/install.sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break fi done if test -z "$ac_aux_dir"; then { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } fi ac_config_guess=$ac_aux_dir/config.guess ac_config_sub=$ac_aux_dir/config.sub ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 echo "configure:798: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" for ac_dir in $PATH; do # Account for people who put trailing slashes in PATH elements. case "$ac_dir/" in /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do if test -f $ac_dir/$ac_prog; then if test $ac_prog = install && grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : else ac_cv_path_install="$ac_dir/$ac_prog -c" break 2 fi fi done ;; esac done IFS="$ac_save_IFS" fi if test "${ac_cv_path_install+set}" = set; then INSTALL="$ac_cv_path_install" else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL="$ac_install_sh" fi fi echo "$ac_t""$INSTALL" 1>&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 echo "configure:851: checking whether ${MAKE-make} sets \${MAKE}" >&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftestmake <<\EOF all: @echo 'ac_maketemp="${MAKE}"' EOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` if test -n "$ac_maketemp"; then eval ac_cv_prog_make_${ac_make}_set=yes else eval ac_cv_prog_make_${ac_make}_set=no fi rm -f conftestmake fi if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then echo "$ac_t""yes" 1>&6 SET_MAKE= else echo "$ac_t""no" 1>&6 SET_MAKE="MAKE=${MAKE-make}" fi # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:880: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_RANLIB="ranlib" break fi done IFS="$ac_save_ifs" test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" fi fi RANLIB="$ac_cv_prog_RANLIB" if test -n "$RANLIB"; then echo "$ac_t""$RANLIB" 1>&6 else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 echo "configure:908: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # This must be in double quotes, not single quotes, because CPP may get # substituted into the Makefile and "${CC-cc}" will confuse make. CPP="${CC-cc} -E" # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:929: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:946: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:963: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP=/lib/cpp fi rm -f conftest* fi rm -f conftest* fi rm -f conftest* ac_cv_prog_CPP="$CPP" fi CPP="$ac_cv_prog_CPP" else ac_cv_prog_CPP="$CPP" fi echo "$ac_t""$CPP" 1>&6 if test $ac_cv_prog_gcc = yes; then echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6 echo "configure:989: checking whether ${CC-cc} needs -traditional" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_pattern="Autoconf.*'x'" cat > conftest.$ac_ext < Autoconf TIOCGETP EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "$ac_pattern" >/dev/null 2>&1; then rm -rf conftest* ac_cv_prog_gcc_traditional=yes else rm -rf conftest* ac_cv_prog_gcc_traditional=no fi rm -f conftest* if test $ac_cv_prog_gcc_traditional = no; then cat > conftest.$ac_ext < Autoconf TCGETA EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "$ac_pattern" >/dev/null 2>&1; then rm -rf conftest* ac_cv_prog_gcc_traditional=yes fi rm -f conftest* fi fi echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6 if test $ac_cv_prog_gcc_traditional = yes; then CC="$CC -traditional" fi fi # Do some error checking and defaulting for the host and target type. # The inputs are: # configure --host=HOST --target=TARGET --build=BUILD NONOPT # # The rules are: # 1. You are not allowed to specify --host, --target, and nonopt at the # same time. # 2. Host defaults to nonopt. # 3. If nonopt is not specified, then host defaults to the current host, # as determined by config.guess. # 4. Target and build default to nonopt. # 5. If nonopt is not specified, then target and build default to host. # The aliases save the names the user supplied, while $host etc. # will get canonicalized. case $host---$target---$nonopt in NONE---*---* | *---NONE---* | *---*---NONE) ;; *) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;; esac # Make sure we can run config.sub. if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } fi echo $ac_n "checking host system type""... $ac_c" 1>&6 echo "configure:1062: checking host system type" >&5 host_alias=$host case "$host_alias" in NONE) case $nonopt in NONE) if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } fi ;; *) host_alias=$nonopt ;; esac ;; esac host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$host" 1>&6 echo $ac_n "checking target system type""... $ac_c" 1>&6 echo "configure:1083: checking target system type" >&5 target_alias=$target case "$target_alias" in NONE) case $nonopt in NONE) target_alias=$host_alias ;; *) target_alias=$nonopt ;; esac ;; esac target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias` target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$target" 1>&6 echo $ac_n "checking build system type""... $ac_c" 1>&6 echo "configure:1101: checking build system type" >&5 build_alias=$build case "$build_alias" in NONE) case $nonopt in NONE) build_alias=$host_alias ;; *) build_alias=$nonopt ;; esac ;; esac build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias` build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$build" 1>&6 test "$host_alias" != "$target_alias" && test "$program_prefix$program_suffix$program_transform_name" = \ NONENONEs,x,x, && program_prefix=${target_alias}- if test "$GCC" = "yes"; then CFLAGS="${CFLAGS} -Wall " else # ugly, there's gotta be a better way to do this... case "${build_os}" in hpux*) CPPFLAGS="${CPPFLAGS} -Ae" CFLAGS="${CFLAGS} +ESlit" if test "$enable_debug" != yes; then CFLAGS="${CFLAGS} +O2" fi ;; esac fi echo $ac_n "checking for main in -lm""... $ac_c" 1>&6 echo "configure:1140: checking for main in -lm" >&5 ac_lib_var=`echo m'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_lib=HAVE_LIB`echo m | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` cat >> confdefs.h <&6 fi echo $ac_n "checking for main in -lcrypto""... $ac_c" 1>&6 echo "configure:1183: checking for main in -lcrypto" >&5 ac_lib_var=`echo crypto'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lcrypto $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_lib=HAVE_LIB`echo crypto | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` cat >> confdefs.h <&6 fi echo $ac_n "checking for SSL_version in -lssl""... $ac_c" 1>&6 echo "configure:1226: checking for SSL_version in -lssl" >&5 ac_lib_var=`echo ssl'_'SSL_version | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lssl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_lib=HAVE_LIB`echo ssl | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` cat >> confdefs.h <&6 fi echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 echo "configure:1275: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #include #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1288: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* ac_cv_header_stdc=yes else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "memchr" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "free" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') #define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF if { (eval echo configure:1355: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_header_stdc=no fi rm -fr conftest* fi fi fi echo "$ac_t""$ac_cv_header_stdc" 1>&6 if test $ac_cv_header_stdc = yes; then cat >> confdefs.h <<\EOF #define STDC_HEADERS 1 EOF fi for ac_hdr in fcntl.h sys/ioctl.h sys/time.h unistd.h openssl/ssl.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:1382: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1392: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done if test "$ac_cv_header_openssl_ssl_h" = "yes" \ -a "$ac_cv_lib_ssl_SSL_version" = "yes" \ -a "$ac_cv_lib_crypto_main" = "yes"; then cat >> confdefs.h <<\EOF #define HAVE_SSL 1 EOF fi echo $ac_n "checking for working const""... $ac_c" 1>&6 echo "configure:1429: checking for working const" >&5 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; } ; return 0; } EOF if { (eval echo configure:1483: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_c_const=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_c_const" 1>&6 if test $ac_cv_c_const = no; then cat >> confdefs.h <<\EOF #define const EOF fi echo $ac_n "checking for size_t""... $ac_c" 1>&6 echo "configure:1504: checking for size_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_size_t=yes else rm -rf conftest* ac_cv_type_size_t=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_size_t" 1>&6 if test $ac_cv_type_size_t = no; then cat >> confdefs.h <<\EOF #define size_t unsigned EOF fi echo $ac_n "checking for long long type""... $ac_c" 1>&6 echo "configure:1537: checking for long long type" >&5 if eval "test \"`echo '$''{'ac_cv_type_long_long'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_type_long_long=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_type_long_long=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_long_long" 1>&6 if test $ac_cv_type_long_long = yes; then cat >> confdefs.h <<\EOF #define u_wide unsigned long long EOF else cat >> confdefs.h <<\EOF #define u_wide unsigned long EOF fi echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6 echo "configure:1575: checking whether time.h and sys/time.h may both be included" >&5 if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #include int main() { struct tm *tp; ; return 0; } EOF if { (eval echo configure:1589: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_time=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_time=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_header_time" 1>&6 if test $ac_cv_header_time = yes; then cat >> confdefs.h <<\EOF #define TIME_WITH_SYS_TIME 1 EOF fi echo $ac_n "checking size of long""... $ac_c" 1>&6 echo "configure:1610: checking size of long" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext < main() { FILE *f=fopen("conftestval", "w"); if (!f) exit(1); fprintf(f, "%d\n", sizeof(long)); exit(0); } EOF if { (eval echo configure:1629: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_long=`cat conftestval` else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_sizeof_long=0 fi rm -fr conftest* fi fi echo "$ac_t""$ac_cv_sizeof_long" 1>&6 cat >> confdefs.h <&6 echo "configure:1649: checking for u_char" >&5 if eval "test \"`echo '$''{'ac_cv_type_u_char'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "(^|[^a-zA-Z_0-9])u_char[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_u_char=yes else rm -rf conftest* ac_cv_type_u_char=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_u_char" 1>&6 if test $ac_cv_type_u_char = no; then cat >> confdefs.h <<\EOF #define u_char unsigned char EOF fi echo $ac_n "checking for u_short""... $ac_c" 1>&6 echo "configure:1682: checking for u_short" >&5 if eval "test \"`echo '$''{'ac_cv_type_u_short'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "(^|[^a-zA-Z_0-9])u_short[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_u_short=yes else rm -rf conftest* ac_cv_type_u_short=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_u_short" 1>&6 if test $ac_cv_type_u_short = no; then cat >> confdefs.h <<\EOF #define u_short unsigned short EOF fi echo $ac_n "checking for u_int""... $ac_c" 1>&6 echo "configure:1715: checking for u_int" >&5 if eval "test \"`echo '$''{'ac_cv_type_u_int'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "(^|[^a-zA-Z_0-9])u_int[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_u_int=yes else rm -rf conftest* ac_cv_type_u_int=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_u_int" 1>&6 if test $ac_cv_type_u_int = no; then cat >> confdefs.h <<\EOF #define u_int unsigned int EOF fi echo $ac_n "checking for u_long""... $ac_c" 1>&6 echo "configure:1748: checking for u_long" >&5 if eval "test \"`echo '$''{'ac_cv_type_u_long'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "(^|[^a-zA-Z_0-9])u_long[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_u_long=yes else rm -rf conftest* ac_cv_type_u_long=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_u_long" 1>&6 if test $ac_cv_type_u_long = no; then cat >> confdefs.h <<\EOF #define u_long unsigned long EOF fi # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6 echo "configure:1784: checking for working alloca.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { char *p = alloca(2 * sizeof(int)); ; return 0; } EOF if { (eval echo configure:1796: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_header_alloca_h=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_alloca_h=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_header_alloca_h" 1>&6 if test $ac_cv_header_alloca_h = yes; then cat >> confdefs.h <<\EOF #define HAVE_ALLOCA_H 1 EOF fi echo $ac_n "checking for alloca""... $ac_c" 1>&6 echo "configure:1817: checking for alloca" >&5 if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < # define alloca _alloca # else # if HAVE_ALLOCA_H # include # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ char *alloca (); # endif # endif # endif # endif #endif int main() { char *p = (char *) alloca(1); ; return 0; } EOF if { (eval echo configure:1850: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_alloca_works=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_func_alloca_works=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_func_alloca_works" 1>&6 if test $ac_cv_func_alloca_works = yes; then cat >> confdefs.h <<\EOF #define HAVE_ALLOCA 1 EOF fi if test $ac_cv_func_alloca_works = no; then # The SVR3 libPW and SVR4 libucb both contain incompatible functions # that cause trouble. Some versions do not even contain alloca or # contain a buggy version. If you still want to use their alloca, # use ar to extract alloca.o from them instead of compiling alloca.c. ALLOCA=alloca.${ac_objext} cat >> confdefs.h <<\EOF #define C_ALLOCA 1 EOF echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 echo "configure:1882: checking whether alloca needs Cray hooks" >&5 if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5 | egrep "webecray" >/dev/null 2>&1; then rm -rf conftest* ac_cv_os_cray=yes else rm -rf conftest* ac_cv_os_cray=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_os_cray" 1>&6 if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:1912: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:1940: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <&6 fi done fi echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 echo "configure:1967: checking stack direction for C alloca" >&5 if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then ac_cv_c_stack_direction=0 else cat > conftest.$ac_ext < addr) ? 1 : -1; } main () { exit (find_stack_direction() < 0); } EOF if { (eval echo configure:1994: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_stack_direction=1 else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_c_stack_direction=-1 fi rm -fr conftest* fi fi echo "$ac_t""$ac_cv_c_stack_direction" 1>&6 cat >> confdefs.h <&6 echo "configure:2019: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:2029: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done for ac_func in getpagesize do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:2058: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:2086: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi done echo $ac_n "checking for working mmap""... $ac_c" 1>&6 echo "configure:2111: checking for working mmap" >&5 if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then ac_cv_func_mmap_fixed_mapped=no else cat > conftest.$ac_ext < #include #include /* This mess was copied from the GNU getpagesize.h. */ #ifndef HAVE_GETPAGESIZE # ifdef HAVE_UNISTD_H # include # endif /* Assume that all systems that can run configure have sys/param.h. */ # ifndef HAVE_SYS_PARAM_H # define HAVE_SYS_PARAM_H 1 # endif # ifdef _SC_PAGESIZE # define getpagesize() sysconf(_SC_PAGESIZE) # else /* no _SC_PAGESIZE */ # ifdef HAVE_SYS_PARAM_H # include # ifdef EXEC_PAGESIZE # define getpagesize() EXEC_PAGESIZE # else /* no EXEC_PAGESIZE */ # ifdef NBPG # define getpagesize() NBPG * CLSIZE # ifndef CLSIZE # define CLSIZE 1 # endif /* no CLSIZE */ # else /* no NBPG */ # ifdef NBPC # define getpagesize() NBPC # else /* no NBPC */ # ifdef PAGESIZE # define getpagesize() PAGESIZE # endif /* PAGESIZE */ # endif /* no NBPC */ # endif /* no NBPG */ # endif /* no EXEC_PAGESIZE */ # else /* no HAVE_SYS_PARAM_H */ # define getpagesize() 8192 /* punt totally */ # endif /* no HAVE_SYS_PARAM_H */ # endif /* no _SC_PAGESIZE */ #endif /* no HAVE_GETPAGESIZE */ #ifdef __cplusplus extern "C" { void *malloc(unsigned); } #else char *malloc(); #endif int main() { char *data, *data2, *data3; int i, pagesize; int fd; pagesize = getpagesize(); /* * First, make a file with some known garbage in it. */ data = malloc(pagesize); if (!data) exit(1); for (i = 0; i < pagesize; ++i) *(data + i) = rand(); umask(0); fd = creat("conftestmmap", 0600); if (fd < 0) exit(1); if (write(fd, data, pagesize) != pagesize) exit(1); close(fd); /* * Next, try to mmap the file at a fixed address which * already has something else allocated at it. If we can, * also make sure that we see the same garbage. */ fd = open("conftestmmap", O_RDWR); if (fd < 0) exit(1); data2 = malloc(2 * pagesize); if (!data2) exit(1); data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1); if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0L)) exit(1); for (i = 0; i < pagesize; ++i) if (*(data + i) != *(data2 + i)) exit(1); /* * Finally, make sure that changes to the mapped area * do not percolate back to the file as seen by read(). * (This is a bug on some variants of i386 svr4.0.) */ for (i = 0; i < pagesize; ++i) *(data2 + i) = *(data2 + i) + 1; data3 = malloc(pagesize); if (!data3) exit(1); if (read(fd, data3, pagesize) != pagesize) exit(1); for (i = 0; i < pagesize; ++i) if (*(data + i) != *(data3 + i)) exit(1); close(fd); unlink("conftestmmap"); exit(0); } EOF if { (eval echo configure:2259: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_mmap_fixed_mapped=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_func_mmap_fixed_mapped=no fi rm -fr conftest* fi fi echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6 if test $ac_cv_func_mmap_fixed_mapped = yes; then cat >> confdefs.h <<\EOF #define HAVE_MMAP 1 EOF fi echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 echo "configure:2282: checking return type of signal handlers" >&5 if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #ifdef signal #undef signal #endif #ifdef __cplusplus extern "C" void (*signal (int, void (*)(int)))(int); #else void (*signal ()) (); #endif int main() { int i; ; return 0; } EOF if { (eval echo configure:2304: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_type_signal=void else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_type_signal=int fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_signal" 1>&6 cat >> confdefs.h <&6 echo "configure:2323: checking for vprintf" >&5 if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char vprintf(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_vprintf) || defined (__stub___vprintf) choke me #else vprintf(); #endif ; return 0; } EOF if { (eval echo configure:2351: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_vprintf=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_vprintf=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'vprintf`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_VPRINTF 1 EOF else echo "$ac_t""no" 1>&6 fi if test "$ac_cv_func_vprintf" != yes; then echo $ac_n "checking for _doprnt""... $ac_c" 1>&6 echo "configure:2375: checking for _doprnt" >&5 if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char _doprnt(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub__doprnt) || defined (__stub____doprnt) choke me #else _doprnt(); #endif ; return 0; } EOF if { (eval echo configure:2403: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func__doprnt=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func__doprnt=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'_doprnt`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_DOPRNT 1 EOF else echo "$ac_t""no" 1>&6 fi fi for ac_func in gettimeofday select socket strdup strerror strtod strtol \ strtoul getopt_long do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:2431: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:2459: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi done trap '' 1 2 15 cat > confcache <<\EOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs. It is not useful on other systems. # If it contains results you don't want to keep, you may remove or edit it. # # By default, configure uses ./config.cache as the cache file, # creating it if it does not exist already. You can give configure # the --cache-file=FILE option to use a different cache file; that is # what configure does when it calls configure scripts in # subdirectories, so they share the cache. # Giving --cache-file=/dev/null disables caching, for debugging configure. # config.status only pays attention to the cache file if you give it the # --recheck option to rerun configure. # EOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. (set) 2>&1 | case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote substitution # turns \\\\ into \\, and sed turns \\ into \). sed -n \ -e "s/'/'\\\\''/g" \ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' ;; esac >> confcache if cmp -s $cache_file confcache; then : else if test -w $cache_file; then echo "updating cache $cache_file" cat confcache > $cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Any assignment to VPATH causes Sun make to only execute # the first set of double-colon rules, so remove it if not needed. # If there is a colon in the path, we need to keep it. if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' fi trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 DEFS=-DHAVE_CONFIG_H # Without the "./", some shells look in PATH for config.status. : ${CONFIG_STATUS=./config.status} echo creating $CONFIG_STATUS rm -f $CONFIG_STATUS cat > $CONFIG_STATUS </dev/null | sed 1q`: # # $0 $ac_configure_args # # Compiler output produced by configure, useful for debugging # configure, is in ./config.log if it exists. ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" for ac_option do case "\$ac_option" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) echo "$CONFIG_STATUS generated by autoconf version 2.13" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; *) echo "\$ac_cs_usage"; exit 1 ;; esac done ac_given_srcdir=$srcdir ac_given_INSTALL="$INSTALL" trap 'rm -fr `echo "stat/Makefile lib/Makefile Makefile gen/Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF $ac_vpsub $extrasub s%@SHELL@%$SHELL%g s%@CFLAGS@%$CFLAGS%g s%@CPPFLAGS@%$CPPFLAGS%g s%@CXXFLAGS@%$CXXFLAGS%g s%@FFLAGS@%$FFLAGS%g s%@DEFS@%$DEFS%g s%@LDFLAGS@%$LDFLAGS%g s%@LIBS@%$LIBS%g s%@exec_prefix@%$exec_prefix%g s%@prefix@%$prefix%g s%@program_transform_name@%$program_transform_name%g s%@bindir@%$bindir%g s%@sbindir@%$sbindir%g s%@libexecdir@%$libexecdir%g s%@datadir@%$datadir%g s%@sysconfdir@%$sysconfdir%g s%@sharedstatedir@%$sharedstatedir%g s%@localstatedir@%$localstatedir%g s%@libdir@%$libdir%g s%@includedir@%$includedir%g s%@oldincludedir@%$oldincludedir%g s%@infodir@%$infodir%g s%@mandir@%$mandir%g s%@CC@%$CC%g s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g s%@INSTALL_DATA@%$INSTALL_DATA%g s%@SET_MAKE@%$SET_MAKE%g s%@RANLIB@%$RANLIB%g s%@CPP@%$CPP%g s%@host@%$host%g s%@host_alias@%$host_alias%g s%@host_cpu@%$host_cpu%g s%@host_vendor@%$host_vendor%g s%@host_os@%$host_os%g s%@target@%$target%g s%@target_alias@%$target_alias%g s%@target_cpu@%$target_cpu%g s%@target_vendor@%$target_vendor%g s%@target_os@%$target_os%g s%@build@%$build%g s%@build_alias@%$build_alias%g s%@build_cpu@%$build_cpu%g s%@build_vendor@%$build_vendor%g s%@build_os@%$build_os%g s%@ALLOCA@%$ALLOCA%g CEOF EOF cat >> $CONFIG_STATUS <<\EOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. ac_file=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_cmds # Line after last line for current file. ac_more_lines=: ac_sed_cmds="" while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file else sed "${ac_end}q" conftest.subs > conftest.s$ac_file fi if test ! -s conftest.s$ac_file; then ac_more_lines=false rm -f conftest.s$ac_file else if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f conftest.s$ac_file" else ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" fi ac_file=`expr $ac_file + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_cmds` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" # A "../" for each directory in $ac_dir_suffix. ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` else ac_dir_suffix= ac_dots= fi case "$ac_given_srcdir" in .) srcdir=. if test -z "$ac_dots"; then top_srcdir=. else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; *) # Relative path. srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" top_srcdir="$ac_dots$ac_given_srcdir" ;; esac case "$ac_given_INSTALL" in [/$]*) INSTALL="$ac_given_INSTALL" ;; *) INSTALL="$ac_dots$ac_given_INSTALL" ;; esac echo creating "$ac_file" rm -f "$ac_file" configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." case "$ac_file" in *Makefile*) ac_comsub="1i\\ # $configure_input" ;; *) ac_comsub= ;; esac ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` sed -e "$ac_comsub s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g s%@top_srcdir@%$top_srcdir%g s%@INSTALL@%$INSTALL%g " $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file fi; done rm -f conftest.s* # These sed commands are passed to sed as "A NAME B NAME C VALUE D", where # NAME is the cpp macro being defined and VALUE is the value it is being given. # # ac_d sets the value in "#define NAME VALUE" lines. ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' ac_dC='\3' ac_dD='%g' # ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_uB='\([ ]\)%\1#\2define\3' ac_uC=' ' ac_uD='\4%g' # ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_eB='$%\1#\2define\3' ac_eC=' ' ac_eD='%g' if test "${CONFIG_HEADERS+set}" != set; then EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF fi for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac echo creating $ac_file rm -f conftest.frag conftest.in conftest.out ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` cat $ac_file_inputs > conftest.in EOF # Transform confdefs.h into a sed script conftest.vals that substitutes # the proper values into config.h.in to produce config.h. And first: # Protect against being on the right side of a sed subst in config.status. # Protect against being in an unquoted here document in config.status. rm -f conftest.vals cat > conftest.hdr <<\EOF s/[\\&%]/\\&/g s%[\\$`]%\\&%g s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp s%ac_d%ac_u%gp s%ac_u%ac_e%gp EOF sed -n -f conftest.hdr confdefs.h > conftest.vals rm -f conftest.hdr # This sed command replaces #undef with comments. This is necessary, for # example, in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. cat >> conftest.vals <<\EOF s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% EOF # Break up conftest.vals because some shells have a limit on # the size of here documents, and old seds have small limits too. rm -f conftest.tail while : do ac_lines=`grep -c . conftest.vals` # grep -c gives empty output for an empty file on some AIX systems. if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi # Write a limited-size here document to conftest.frag. echo ' cat > conftest.frag <> $CONFIG_STATUS sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS echo 'CEOF sed -f conftest.frag conftest.in > conftest.out rm -f conftest.in mv conftest.out conftest.in ' >> $CONFIG_STATUS sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail rm -f conftest.vals mv conftest.tail conftest.vals done rm -f conftest.vals cat >> $CONFIG_STATUS <<\EOF rm -f conftest.frag conftest.h echo "/* $ac_file. Generated automatically by configure. */" > conftest.h cat conftest.in >> conftest.h rm -f conftest.in if cmp -s $ac_file conftest.h 2>/dev/null; then echo "$ac_file is unchanged" rm -f conftest.h else # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" fi rm -f $ac_file mv conftest.h $ac_file fi fi; done EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF exit 0 EOF chmod +x $CONFIG_STATUS rm -fr confdefs* $ac_clean_files test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/configure.in ================================================ dnl Process this file with autoconf to produce a configure script. AC_INIT(timer.h) AC_CONFIG_HEADER(config.h) AC_ARG_ENABLE(debug, [ --enable-debug enable debug support]) if test "$enable_debug" = yes; then CPPFLAGS="${CPPFLAGS} -DDEBUG" else CPPFLAGS="${CPPFLAGS} -DNDEBUG" fi CPPFLAGS="${CPPFLAGS} -D_GNU_SOURCE -D_XOPEN_SOURCE" LDFLAGS="${LDFLAGS}" dnl Checks for programs. AC_PROG_CC AC_PROG_INSTALL AC_PROG_MAKE_SET AC_PROG_RANLIB AC_PROG_GCC_TRADITIONAL AC_CANONICAL_SYSTEM if test "$GCC" = "yes"; then CFLAGS="${CFLAGS} -Wall" else # ugly, there's gotta be a better way to do this... case "${build_os}" in hpux*) CPPFLAGS="${CPPFLAGS} -Ae" CFLAGS="${CFLAGS} +ESlit" if test "$enable_debug" != yes; then CFLAGS="${CFLAGS} +O2" fi ;; esac fi dnl Checks for libraries. dnl Replace `main' with a function in -lm: AC_CHECK_LIB(m, main) AC_CHECK_LIB(crypto, main) AC_CHECK_LIB(ssl, SSL_version) dnl Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS(fcntl.h sys/ioctl.h sys/time.h unistd.h openssl/ssl.h) if test "$ac_cv_header_openssl_ssl_h" = "yes" \ -a "$ac_cv_lib_ssl_SSL_version" = "yes" \ -a "$ac_cv_lib_crypto_main" = "yes"; then AC_DEFINE(HAVE_SSL) fi dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_TYPE_SIZE_T AC_TYPE_LONG_LONG AC_HEADER_TIME AC_CHECK_SIZEOF(long) AC_CHECK_TYPE(u_char, unsigned char) AC_CHECK_TYPE(u_short, unsigned short) AC_CHECK_TYPE(u_int, unsigned int) AC_CHECK_TYPE(u_long, unsigned long) dnl Checks for library functions. AC_FUNC_ALLOCA AC_FUNC_MMAP AC_TYPE_SIGNAL AC_FUNC_VPRINTF AC_CHECK_FUNCS(gettimeofday select socket strdup strerror strtod strtol \ strtoul getopt_long) AC_OUTPUT(stat/Makefile lib/Makefile Makefile gen/Makefile) ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/conn.c ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include #include #include #include #include #include void conn_init (Conn *conn) { #ifdef UW_CALL_STATS static u_long next_conn_id = 0; #endif /* UW_CALL_STATS */ conn->hostname = param.server; conn->hostname_len = strlen (param.server); if (param.lb_ports.num_ports > 0) { conn->port = param.lb_ports.port[param.lb_ports.cur_port]; param.lb_ports.cur_port = (param.lb_ports.cur_port + 1)%param.lb_ports.num_ports; } else conn->port = param.port; #ifdef HAVE_EPOLL conn->added_to_epoll = 0; #endif #ifdef UW_CALL_STATS conn->id = next_conn_id++; #endif /* UW_CALL_STATS */ conn->sd = -1; conn->timed_out = 0; conn->myport = -1; conn->line.iov_base = conn->line_buf; if (param.server_name) { conn->fqdname = param.server_name; conn->fqdname_len = strlen (param.server_name); } else { conn->fqdname = conn->hostname; conn->fqdname_len = conn->hostname_len; } #ifdef HAVE_SSL if (param.use_ssl) { conn->ssl = SSL_new (ssl_ctx); if (!conn->ssl) { ERR_print_errors_fp (stderr); exit (-1); } if (param.ssl_cipher_list) { /* set order of ciphers */ int ssl_err = SSL_set_ciphersuites (conn->ssl, param.ssl_cipher_list); if (DBG > 2) fprintf (stderr, "core_ssl_connect: set_cipher_list returned %d\n", ssl_err); } } #endif } void conn_deinit (Conn *conn) { assert (conn->sd < 0 && conn->state != S_FREE); assert (!conn->sendq); assert (!conn->recvq); assert (!conn->watchdog); conn->state = S_FREE; #ifdef HAVE_SSL if (conn->ssl) { SSL_free (conn->ssl); } #endif } ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/conn.h ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef conn_h #define conn_h #include "config.h" #include #include #include #include #ifdef HAVE_SSL # include # include #endif /* Maximum header line length that we can process properly. Longer lines will be treated as if they were only this long (i.e., they will be truncated). */ #define MAX_HDR_LINE_LEN 1024 struct Call; typedef enum Conn_State { S_INITIAL, S_CONNECTING, S_CONNECTED, S_REPLY_STATUS, S_REPLY_HEADER, S_REPLY_CONTINUE, S_REPLY_DATA, S_REPLY_CHUNKED, S_REPLY_FOOTER, S_REPLY_DONE, S_CLOSING, S_FREE } Conn_State; typedef struct Conn { Object obj; Conn_State state; struct Conn *next; struct Call *sendq; /* calls whose request needs to be sent */ struct Call *sendq_tail; struct Call *recvq; /* calls waiting for a reply */ struct Call *recvq_tail; Timer *watchdog; struct { Time time_connect_start; /* time connect() got called */ #ifdef UW_CALL_STATS Time time_to_connect; /* time to connect */ Time time_of_timeout; /* time connection timeout occurs (if it occurs) */ #endif /* UW_CALL_STATS */ u_int num_calls_completed; /* # of calls that completed */ u_int num_calls; /* # of calls that should be completed */ #ifdef UW_STABLE_STATS u_int is_stable; /* true when not ramping up or ramping down */ #endif /* UW_STABLE_STATS */ } basic; /* maintained by stat/stats_basic.c */ size_t hostname_len; const char *hostname; /* server's hostname (or 0 for default) */ size_t fqdname_len; const char *fqdname; /* fully qualified server name (or 0) */ int log_index; /* The index of the log that is the */ char local_ip[16]; /* The local-ip to bind this connection to. */ int port; /* server's port (or -1 for default) */ int sd; /* socket descriptor */ #ifdef HAVE_EPOLL int added_to_epoll; /* has the sd been added to epoll event set? */ #endif int myport; /* local port number or -1 */ /* Since replies are read off the socket sequentially, much of the reply-processing related state can be kept here instead of in the reply structure: */ struct iovec line; /* buffer used to parse reply headers */ size_t content_length; /* content length (or INF if unknown) */ u_int has_body : 1; /* does reply have a body? */ u_int is_chunked : 1; /* is the reply chunked? */ int timed_out; /* did this connection time out?*/ char line_buf[MAX_HDR_LINE_LEN]; /* default line buffer */ #ifdef HAVE_SSL SSL *ssl; /* SSL connection info */ #endif u_long id; } Conn; extern int max_num_conn; extern Conn *conn; /* Initialize the new connection object C. */ extern void conn_init (Conn *c); /* Destroy the connection-specific state in connection object C. */ extern void conn_deinit (Conn *c); #define conn_new() ((Conn *) object_new (OBJ_CONN)) #define conn_inc_ref(c) object_inc_ref ((Object *) (c)) #define conn_dec_ref(c) object_dec_ref ((Object *) (c)) #endif /* conn_h */ ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/core.c ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_EPOLL #include #endif #include #include #include #include #include /* grrr, must come after sys/types.h for BSD */ #include #include #include #include #include #include #include #include #include #define HASH_TABLE_SIZE 1024 /* can't have more than this many servers */ #define MIN_IP_PORT IPPORT_RESERVED #define MAX_IP_PORT 65535 #define BITSPERLONG (8*sizeof (u_long)) static int running = 1; static int iteration; static u_long max_burst_len; static big_fd_set rdfds, wrfds; static int min_sd = 0x7fffffff, max_sd = 0, alloced_sd_to_conn = 0; static struct timeval select_timeout; #ifdef HAVE_EPOLL static int epoll_fd; static struct epoll_event *epoll_events; static int epoll_max_events; static int epoll_timeout; #endif /* HAVE_EPOLL */ static struct sockaddr_in myaddr; Conn **sd_to_conn; static u_long port_free_map[((MAX_IP_PORT - MIN_IP_PORT + BITSPERLONG) / BITSPERLONG)]; static char http10req[] = " HTTP/1.0\r\nUser-Agent: httperf/"VERSION"\r\nHost: "; static char http11req[] = " HTTP/1.1\r\nUser-Agent: httperf/"VERSION"\r\nHost: "; static char http10req_nohost[] = " HTTP/1.0\r\nUser-Agent: httperf/"VERSION"\r\n"; static char http11req_nohost[] = " HTTP/1.1\r\nUser-Agent: httperf/"VERSION"\r\n"; #ifndef SOL_TCP # define SOL_TCP 6 /* probably ought to do getprotlbyname () */ #endif #ifdef TIME_CORE_LOOP static float timer_tick_time, select_time, work_time; static Time core_loop_timer_start; #endif #ifdef TIME_CORE_LOOP # define TIME_BEGIN() core_loop_timer_start = timer_now_forced() # define TIME_END(var) var += (timer_now_forced() - core_loop_timer_start) #else # define TIME_BEGIN() # define TIME_END(var) #endif #ifdef TIME_SYSCALLS # define SYSCALL(n,s) \ { \ Time start, stop; \ do \ { \ errno = 0; \ start = timer_now_forced (); \ s; /* execute the syscall */ \ stop = timer_now_forced (); \ syscall_time[SC_##n] += stop - start; \ ++syscall_count[SC_##n]; \ } \ while (errno == EINTR); \ } enum Syscalls { SC_BIND, SC_CONNECT, SC_READ, SC_SELECT, SC_SOCKET, SC_WRITEV, SC_SSL_READ, SC_SSL_WRITEV, SC_EPOLL_CREATE, SC_EPOLL_CTL, SC_EPOLL_WAIT, SC_NUM_SYSCALLS }; static const char * const syscall_name[SC_NUM_SYSCALLS] = { "bind", "connct", "read", "select", "socket", "writev", "ssl_read", "ssl_writev", "epoll_create", "epoll_ctl", "epoll_wait" }; static Time syscall_time[SC_NUM_SYSCALLS]; static u_int syscall_count[SC_NUM_SYSCALLS]; #else # define SYSCALL(n,s) \ { \ do \ { \ errno = 0; \ s; \ } \ while (errno == EINTR); \ } #endif struct hash_entry { const char *hostname; int port; struct sockaddr_in sin; } hash_table[HASH_TABLE_SIZE]; void process_spec_timeout(Conn * c); void BIG_FD_CLR(int fd, big_fd_set *fdsetp) { unsigned long _tmp = fd / __BIG_NFDBITS; unsigned long _rem = fd % __BIG_NFDBITS; fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem); } int BIG_FD_ISSET(int fd, big_fd_set *fdsetp) { unsigned long _tmp = fd / __BIG_NFDBITS; unsigned long _rem = fd % __BIG_NFDBITS; return (fdsetp->fds_bits[_tmp] & (1UL<<_rem)) != 0; } void BIG_FD_SET(int fd, big_fd_set *fdsetp) { unsigned long _tmp = fd / __BIG_NFDBITS; unsigned long _rem = fd % __BIG_NFDBITS; fdsetp->fds_bits[_tmp] |= (1UL<<_rem); } static int hash_code (const char *server, size_t server_len, int port) { u_char *cp = (u_char *) server; u_long h = port; u_long g; int ch; /* Basically the ELF hash algorithm: */ while ((ch = *cp++) != '\0') { h = (h << 4) + ch; if ((g = (h & 0xf0000000)) != 0) { h ^= g >> 24; h &= ~g; } } return h; } static struct hash_entry* hash_enter (const char *server, size_t server_len, int port, struct sockaddr_in *sin) { struct hash_entry *he; int index = hash_code (server, server_len, port) % HASH_TABLE_SIZE; printf("hash_enter: %s %d\n", server, port); while (hash_table[index].hostname) { ++index; if (index >= HASH_TABLE_SIZE) index = 0; } he = hash_table + index; he->hostname = server; he->port = port; he->sin = *sin; return he; } struct sockaddr_in* hash_lookup (const char *server, size_t server_len, int port) { int index, start_index; index = start_index = hash_code (server, server_len, port) % HASH_TABLE_SIZE; while (hash_table[index].hostname) { if (hash_table[index].port == port && strcmp (hash_table[index].hostname, server) == 0) return &hash_table[index].sin; ++index; if (index >= HASH_TABLE_SIZE) index = 0; if (index == start_index) break; } return 0; } static int lffs (long w) { int r; if (sizeof (w) == sizeof (int)) r = ffs (w); else { r = ffs (w); #if SIZEOF_LONG > 4 if (r == 0) { r = ffs (w >> (8*sizeof (int))); if (r > 0) r += 8*sizeof (int); } #endif } return r; } static void port_put (int port) { int i, bit; port -= MIN_IP_PORT; i = port / BITSPERLONG; bit = port % BITSPERLONG; port_free_map[i] |= (1UL << bit); } static int port_get (void) { static u_long mask = ~0UL; static int previous = 0; int port, bit, i; i = previous; if ((port_free_map[i] & mask) == 0) { do { ++i; if (i >= NELEMS (port_free_map)) i = 0; if (i == previous) { if (DBG > 0) fprintf (stderr, "%s.port_get: Yikes! I'm out of port numbers!\n", prog_name); return -1; } } while (port_free_map[i] == 0); mask = ~0UL; } previous = i; bit = lffs (port_free_map[i] & mask) - 1; if (bit >= BITSPERLONG - 1) mask = 0; else mask = ~((1UL << (bit + 1)) - 1); // commented by aansaarii // if the port is utilized by another program, it will be utilized by httperf // and it will never have a chance to be freed, httperf will eventually run out of ports //port_free_map[i] &= ~(1UL << bit); port = bit + i*BITSPERLONG + MIN_IP_PORT; return port; } static void conn_failure (Conn *s, int err) { Any_Type arg; arg.l = err; event_signal (EV_CONN_FAILED, (Object *) s, arg); core_close (s); } static void conn_timeout (Timer *t, Any_Type arg) { Conn *s = arg.vp; Time now; Call *c; #ifdef UW_CALL_STATS u_long conn_id; #endif /* UW_CALL_STATS */ assert (object_is_conn (s)); s->watchdog = 0; #ifdef UW_CALL_STATS conn_id = s->id; #endif /* UW_CALL_STATS */ if (DBG > 0) { c = 0; if (s->sd >= 0) { now = timer_now (); if (BIG_FD_ISSET (s->sd, &rdfds) && s->recvq && now >= s->recvq->timeout) c = s->recvq; else if (BIG_FD_ISSET (s->sd, &wrfds) && s->sendq && now >= s->sendq->timeout) c = s->sendq; } if (DBG > 0) { fprintf (stderr, "connection_timeout"); if (c) fprintf (stderr, ".%lu", c->id); fprintf (stderr, ": t=%p, connection=%p\n", t, s); } } arg.l = 0; event_signal (EV_CONN_TIMEOUT, (Object *) s, arg); #ifdef UW_CALL_STATS if (s->id == conn_id) { core_close (s); } #else core_close (s); #endif /* UW_CALL_STATS */ } static void set_active (Conn *s, big_fd_set *fdset) { int sd = s->sd; BIG_FD_SET (sd, fdset); if (sd < min_sd) min_sd = sd; if (sd >= max_sd) max_sd = sd; } #ifdef HAVE_EPOLL static void update_epoll_event (Conn *s) { struct epoll_event evt; int epoll_op, rv; int sd = s->sd; evt.events = 0; if (BIG_FD_ISSET(sd, &rdfds)) evt.events |= EPOLLIN; if (BIG_FD_ISSET(sd, &wrfds)) evt.events |= EPOLLOUT; evt.data.fd = sd; if (s->added_to_epoll) { epoll_op = EPOLL_CTL_MOD; } else { epoll_op = EPOLL_CTL_ADD; s->added_to_epoll = 1; } SYSCALL (EPOLL_CTL, rv = epoll_ctl(epoll_fd, epoll_op, sd, &evt)); if (rv != 0) { fprintf (stderr, "%s: epoll_ctl failed on sd %d: %s\n", prog_name, sd, strerror(errno)); exit (1); } } #endif /* HAVE_EPOLL */ static void schedule_timeouts (Conn *s) { Any_Type arg; Time timeout = 0.0; if (s->watchdog) return; if (s->sendq) timeout = s->sendq->timeout; if (s->recvq && (timeout == 0.0 || timeout > s->recvq->timeout)) timeout = s->recvq->timeout; if (timeout > 0.0) { arg.vp = s; s->watchdog = timer_schedule (conn_timeout, arg, timeout - timer_now ()); } } static void interested_in_reading (Conn *s) { set_active (s, &rdfds); #ifdef HAVE_EPOLL if (param.use_epoll) update_epoll_event (s); #endif schedule_timeouts (s); } static void interested_in_reading_no_timeout (Conn *s) { set_active (s, &rdfds); #ifdef HAVE_EPOLL if (param.use_epoll) update_epoll_event (s); #endif } static void interested_in_writing (Conn *s) { set_active(s, &wrfds); #ifdef HAVE_EPOLL if (param.use_epoll) update_epoll_event (s); #endif schedule_timeouts (s); } static void do_send (Conn *conn) { int async_errno; socklen_t len; struct iovec *iovp; int sd = conn->sd; ssize_t nsent = 0; Any_Type arg; Call *call; while (1) { call = conn->sendq; assert (call); arg.l = 0; event_signal (EV_CALL_SEND_RAW_DATA, (Object *) call, arg); #ifdef HAVE_SSL if (conn->ssl) { extern ssize_t SSL_writev (SSL *, const struct iovec *, int); SYSCALL (SSL_WRITEV, nsent = SSL_writev(conn->ssl, call->req.iov + call->req.iov_index, (NELEMS (call->req.iov) - call->req.iov_index))); } else #endif { SYSCALL (WRITEV, nsent = writev (sd, call->req.iov + call->req.iov_index, (NELEMS (call->req.iov) - call->req.iov_index))); } if (DBG > 0) fprintf (stderr, "do_send.%lu: wrote %ld bytes on %p\n", call->id, (long) nsent, conn); if (nsent < 0) { if (errno == EAGAIN) return; len = sizeof (async_errno); if (getsockopt (sd, SOL_SOCKET, SO_ERROR, &async_errno, &len) == 0 && async_errno != 0) errno = async_errno; if (DBG > 0) fprintf (stderr, "%s.do_send: writev() failed: %s\n", prog_name, strerror (errno)); conn_failure (conn, errno); return; } call->req.size += nsent; iovp = call->req.iov + call->req.iov_index; while (iovp < call->req.iov + NELEMS (call->req.iov)) { if (nsent < iovp->iov_len) { iovp->iov_len -= nsent; iovp->iov_base = (caddr_t) ((char *) iovp->iov_base + nsent); break; } else { /* we're done with this fragment: */ nsent -= iovp->iov_len; *iovp = call->req.iov_saved; ++iovp; call->req.iov_saved = *iovp; } } call->req.iov_index = iovp - call->req.iov; if (call->req.iov_index < NELEMS (call->req.iov)) { #ifdef UW_DYNOUT if (call->timelimit != 0) { call->timeout = timer_now () + call->timelimit; } else { call->timeout = param.timeout ? timer_now () + param.timeout : 0.0; } #else /* there are more header bytes to write */ call->timeout = param.timeout ? timer_now () + param.timeout : 0.0; #endif /* UW_DYNOUT */ interested_in_writing (conn); return; } /* we're done with sending this request */ conn->sendq = call->sendq_next; if (!conn->sendq) { conn->sendq_tail = 0; BIG_FD_CLR (sd, &wrfds); } arg.l = 0; event_signal (EV_CALL_SEND_STOP, (Object *) call, arg); if (conn->state >= S_CLOSING) { call_dec_ref (call); return; } /* get ready to receive matching reply (note that we implicitly pass on the reference to the call from the sendq to the recvq): */ call->recvq_next = 0; if (!conn->recvq) conn->recvq = conn->recvq_tail = call; else { conn->recvq_tail->recvq_next = call; conn->recvq_tail = call; } #ifdef UW_DYNOUT if (call->timelimit != 0) { call->timeout = call->timelimit + param.think_timeout; } else { call->timeout = param.timeout + param.think_timeout; } #else call->timeout = param.timeout + param.think_timeout; #endif /* UW_DYNOUT */ if (call->timeout > 0.0) call->timeout += timer_now (); interested_in_reading (conn); if (conn->state < S_REPLY_STATUS) conn->state = S_REPLY_STATUS; /* expecting reply status */ if (!conn->sendq) return; arg.l = 0; event_signal (EV_CALL_SEND_START, (Object *) conn->sendq, arg); if (conn->state >= S_CLOSING) return; } } static void recv_done (Call *call) { Conn *conn = call->conn; Any_Type arg; conn->recvq = call->recvq_next; if (!conn->recvq) { BIG_FD_CLR (conn->sd, &rdfds); conn->recvq_tail = 0; } /* we're done with receiving this request */ arg.l = 0; event_signal (EV_CALL_RECV_STOP, (Object *) call, arg); call_dec_ref (call); } char buf[1048576]; static void do_recv (Conn *s) { char *cp; Call *c = s->recvq; int i, saved_errno; ssize_t nread = 0; size_t buf_len; assert (c); #ifdef HAVE_SSL if (s->ssl) { SYSCALL (SSL_READ, nread = SSL_read (s->ssl, buf, sizeof (buf) - 1)); } else #endif { SYSCALL (READ, nread = read (s->sd, buf, sizeof (buf) - 1)); } saved_errno = errno; if (nread <= 0) { if (DBG > 0) { fprintf (stderr, "do_recv.%lu: received %lu reply bytes on %p\n", c->id, (u_long) (c->reply.header_bytes + c->reply.content_bytes), s); if (nread < 0) fprintf (stderr, "%s.do_recv: read() failed: %s\n", prog_name, strerror (saved_errno)); } if (nread < 0) { if (saved_errno != EAGAIN) conn_failure (s, saved_errno); } else if (s->state != S_REPLY_DATA) conn_failure (s, ECONNRESET); else { if (s->state < S_CLOSING) s->state = S_REPLY_DONE; recv_done (c); } return; } buf[nread] = '\0'; /* ensure buffer is '\0' terminated */ if (DBG > 3) { /* dump received data in hex & ascii: */ fprintf (stderr, "do_recv.%lu: received reply data:\n", c->id); for (cp = buf; cp < buf + nread; ) { fprintf (stderr, " %04x:", (int) (c->reply.header_bytes + c->reply.content_bytes + (cp - buf))); for (i = 0; i < 16 && i < buf + nread - cp; ++i) fprintf (stderr, " %02x", cp[i] & 0xff); i *= 3; while (i++ < 50) fputc (' ', stderr); for (i = 0; i < 16 && cp < buf + nread; ++i, ++cp) fprintf (stderr, "%c", isprint (*cp) ? *cp : '.'); fprintf (stderr, "\n"); } } /* process the replies in this buffer: */ buf_len = nread; cp = buf; do { c = s->recvq; assert (c); http_process_reply_bytes (c, &cp, &buf_len); if (s->content_length == 0) { if (DBG > 0) { fprintf(stderr, "c = %p cp = %p buf_len = %d\n", c, cp, (int) buf_len); fprintf(stderr, "do_recv: content length = 0"); } /* NOTE: httperf doesn't look at the content length * when determining how much body to read so a zero byte * file followed by a footer causes problems. * But then it also looks like httperf doesn't handle * Content-length + a footer properly for non zero byte files. */ if (buf_len == 0) { s->state = S_REPLY_DONE; if (DBG > 0) { fprintf(stderr, "do_recv: setting state to S_REPLY_DONE\n"); } } } if (s->state == S_REPLY_DONE) { recv_done (c); if (s->state >= S_CLOSING) return; s->state = S_REPLY_STATUS; } } while (buf_len > 0); if (s->recvq) interested_in_reading_no_timeout (c->conn); } struct sockaddr_in* core_addr_intern (const char *server, size_t server_len, int port) { struct sockaddr_in sin; struct hash_entry *h; struct hostent *he; Any_Type arg; memset (&sin, 0, sizeof (sin)); sin.sin_family = AF_INET; sin.sin_port = htons (port); arg.cvp = server; event_signal (EV_HOSTNAME_LOOKUP_START, 0, arg); he = gethostbyname (server); event_signal (EV_HOSTNAME_LOOKUP_STOP, 0, arg); if (he) { if (he->h_addrtype != AF_INET || he->h_length != sizeof (sin.sin_addr)) { fprintf (stderr, "%s: can't deal with addr family %d or size %d\n", prog_name, he->h_addrtype, he->h_length); exit (1); } memcpy (&sin.sin_addr, he->h_addr_list[0], sizeof (sin.sin_addr)); } else { if (!inet_aton (server, &sin.sin_addr)) { fprintf (stderr, "%s.core_addr_intern: invalid server address %s\n", prog_name, server); exit (1); } } h = hash_enter (server, server_len, port, &sin); if (!h) return 0; return &h->sin; } #ifdef HAVE_EPOLL static void init_epoll (void) { int epoll_events_size; /* How many epoll events should we get at once? I'll do one for now. FIXME: Figure out how many to use, or add a command-line parameter, or something. */ epoll_max_events = 2048; /* Allocate epoll events. */ epoll_events_size = epoll_max_events * sizeof(struct epoll_event); epoll_events = (struct epoll_event *) malloc(epoll_events_size); if (!epoll_events) { fprintf (stderr, "%s: failed to allocate space for epoll events: %s\n", prog_name, strerror (errno)); exit (1); } /* Create epoll file descriptor. */ SYSCALL (EPOLL_WAIT, epoll_fd = epoll_create(epoll_max_events)); if (epoll_fd < 0) { fprintf (stderr, "%s: failed to allocate space for epoll events: %s\n", prog_name, strerror (errno)); exit (1); } /* Determine epoll timeout (the same way the select() timeout is set in core_init() below). */ #ifdef DONT_POLL epoll_timeout = (int) (TIMER_INTERVAL * 1e3); #else epoll_timeout = 0; #endif } #endif /* HAVE_EPOLL */ void core_init (void) { struct rlimit rlimit; int port = param.port; int i; memset (&hash_table, 0, sizeof (hash_table)); memset (&rdfds, 0, sizeof (rdfds)); memset (&wrfds, 0, sizeof (wrfds)); memset (&myaddr, 0, sizeof (myaddr)); memset (&port_free_map, 0xff, sizeof (port_free_map)); /* Don't disturb just because a TCP connection closed on us... */ signal (SIGPIPE, SIG_IGN); #ifdef DONT_POLL /* This causes select() to take several milliseconds on both Linux/x86 and HP-UX 10.20. */ select_timeout.tv_sec = (u_long) TIMER_INTERVAL; select_timeout.tv_usec = (u_long) (TIMER_INTERVAL * 1e6); #else /* This causes httperf to become a CPU hog as it polls for filedescriptors to become readable/writable. This is OK as long as httperf is the only (interesting) user-level process that executes on a machine. */ select_timeout.tv_sec = 0; select_timeout.tv_usec = 0; #endif /* initialize epoll stuff */ #ifdef HAVE_EPOLL if (param.use_epoll) init_epoll(); #endif /* boost open file limit to the max: */ /* if (getrlimit (RLIMIT_NOFILE, &rlimit) < 0) { fprintf (stderr, "%s: failed to get number of open file limit: %s", prog_name, strerror (errno)); exit (1); } if (rlimit.rlim_max > BIG_FD_SETSIZE) { fprintf (stderr, "%s: warning: open file limit = %ld > BIG_FD_SETSIZE\n" " limiting max. # of open files to BIG_FD_SETSIZE = %ld\n", prog_name, (long int) rlimit.rlim_max, (long int) BIG_FD_SETSIZE); rlimit.rlim_max = BIG_FD_SETSIZE; } rlimit.rlim_cur = rlimit.rlim_max; if (setrlimit (RLIMIT_NOFILE, &rlimit) < 0) { fprintf (stderr, "%s: failed to increase number of open file limit: %s", prog_name, strerror (errno)); exit (1); } */ fprintf (stderr, "%s: maximum number of open descriptors = %lld\n", prog_name, (long long) rlimit.rlim_max); if (param.server) { if (param.lb_ports.num_ports > 0) { for(i=0; i 2) fprintf (stderr, "Adding server: %s port: %d\n", param.server, port); core_addr_intern (param.server, strlen (param.server), port); } } else { core_addr_intern (param.server, strlen (param.server), port); } } } #ifdef HAVE_SSL void core_ssl_connect (Conn *s) { Any_Type arg; int ssl_err; if (DBG > 2) fprintf (stderr, "core_ssl_connect(conn=%p)\n", (void *) s); if (SSL_set_fd (s->ssl, s->sd) == 0) { ERR_print_errors_fp (stderr); exit (-1); } ssl_err = SSL_connect (s->ssl); if (ssl_err < 0) { int reason = SSL_get_error(s->ssl, ssl_err); if (reason == SSL_ERROR_WANT_READ || reason == SSL_ERROR_WANT_WRITE) { if (DBG > 2) fprintf (stderr, "core_ssl_connect: want to %s more...\n", (reason == SSL_ERROR_WANT_READ) ? "read" : "write"); if (reason == SSL_ERROR_WANT_READ && !BIG_FD_ISSET (s->sd, &rdfds)) { BIG_FD_CLR (s->sd, &wrfds); interested_in_reading (s); } else if (reason == SSL_ERROR_WANT_WRITE && !BIG_FD_ISSET (s->sd, &wrfds)) { BIG_FD_CLR (s->sd, &rdfds); interested_in_writing (s); } s->state = S_CONNECTING; return; } fprintf (stderr, "%s: failed to connect to SSL server (err=%d, reason=%d)\n", prog_name, ssl_err, reason); ERR_print_errors_fp (stderr); exit (-1); } s->state = S_CONNECTED; if (DBG > 0) fprintf (stderr, "core_ssl_connect: SSL is connected!\n"); if (DBG > 1) { SSL_CIPHER *ssl_cipher; ssl_cipher = SSL_get_current_cipher (s->ssl); if (!ssl_cipher) fprintf (stderr, "core_ssl_connect: server refused all client cipher " "suites!\n"); // else // fprintf (stderr, "core_ssl_connect: cipher=%s, valid=%d, id=%lu\n", // ssl_cipher->name, ssl_cipher->valid, ssl_cipher->id); } arg.l = 0; event_signal (EV_CONN_CONNECTED, (Object *) s, arg); } #endif /* HAVE_SSL */ int core_connect (Conn *s) { int sd, result, async_errno; socklen_t len; int saved_err = CONN_ERR_NOT_SET; struct sockaddr_in *sin; struct linger linger; int myport, optval; Any_Type arg; static int prev_iteration = -1; static u_long burst_len; if (iteration == prev_iteration) ++burst_len; else { if (burst_len > max_burst_len) max_burst_len = burst_len; burst_len = 1; prev_iteration = iteration; } SYSCALL (SOCKET, sd = socket (AF_INET, SOCK_STREAM, 0)); saved_err = errno; if (sd < 0) { if (DBG > 0) fprintf (stderr, "%s.core_connect.socket: %s (max_sd=%d)\n", prog_name, strerror (errno), max_sd); goto failure; } if (fcntl (sd, F_SETFL, O_NONBLOCK) < 0) { saved_err = errno; fprintf (stderr, "%s.core_connect.fcntl: %s\n", prog_name, strerror (errno)); goto failure; } if (param.close_with_reset) { linger.l_onoff = 1; linger.l_linger = 0; if (setsockopt (sd, SOL_SOCKET, SO_LINGER, &linger, sizeof (linger)) < 0) { saved_err = errno; fprintf (stderr, "%s.core_connect.setsockopt(SO_LINGER): %s\n", prog_name, strerror (errno)); goto failure; } } /* Disable Nagle algorithm so we don't delay needlessly when pipelining requests. */ optval = 1; if (setsockopt (sd, SOL_TCP, TCP_NODELAY, &optval, sizeof (optval)) < 0) { saved_err = errno; fprintf (stderr, "%s.core_connect.setsockopt(SO_SNDBUF): %s\n", prog_name, strerror (errno)); goto failure; } optval = param.send_buffer_size; if (setsockopt (sd, SOL_SOCKET, SO_SNDBUF, &optval, sizeof (optval)) < 0) { saved_err = errno; fprintf (stderr, "%s.core_connect.setsockopt(SO_SNDBUF): %s\n", prog_name, strerror (errno)); goto failure; } optval = param.recv_buffer_size; if (setsockopt (sd, SOL_SOCKET, SO_RCVBUF, &optval, sizeof (optval)) < 0) { saved_err = errno; fprintf (stderr, "%s.core_connect.setsockopt(SO_SNDBUF): %s\n", prog_name, strerror (errno)); goto failure; } s->sd = sd; if (sd >= alloced_sd_to_conn) { size_t size, old_size; old_size = alloced_sd_to_conn * sizeof (sd_to_conn[0]); alloced_sd_to_conn += 2048; size = alloced_sd_to_conn * sizeof (sd_to_conn[0]); if (sd_to_conn) { sd_to_conn = realloc (sd_to_conn, size); saved_err = errno; } else { sd_to_conn = malloc (size); saved_err = errno; } if (!sd_to_conn) { if (DBG > 0) fprintf (stderr, "%s.core_connect.realloc: %s\n", prog_name, strerror (errno)); goto failure; } memset ((char *) sd_to_conn + old_size, 0, size - old_size); } assert (!sd_to_conn[sd]); sd_to_conn[sd] = s; sin = hash_lookup (s->hostname, s->hostname_len, s->port); if (!sin) { saved_err = CONN_ERR_HASH_LOOKUP_FAILED; if (DBG > 0) fprintf (stderr, "%s.core_connect: unknown server/port %s:%d\n", prog_name, s->hostname, s->port); goto failure; } arg.l = 0; event_signal (EV_CONN_CONNECTING, (Object *) s, arg); if (s->state >= S_CLOSING) { saved_err = CONN_ERR_STATE_PAST_CLOSING; goto failure; } if (param.hog) { while (1) { myport = port_get (); if (myport < 0) { saved_err = CONN_ERR_NO_MORE_PORTS; goto failure; } if (s->local_ip && s->local_ip[0] != '\0') { inet_pton(AF_INET, s->local_ip, &(myaddr.sin_addr)); } myaddr.sin_family = AF_INET; myaddr.sin_port = htons (myport); SYSCALL (BIND, result = bind (sd, (struct sockaddr *) &myaddr, sizeof (myaddr))); saved_err = errno; if (result == 0){ // edited by aansaarii // set the port as allocated if it is binded to this httperf process int port = myport - MIN_IP_PORT; int i = port / BITSPERLONG; int bit = port % BITSPERLONG; port_free_map[i] &= ~(1UL << bit); // end edit break; } if (errno != EADDRINUSE && errno == EADDRNOTAVAIL) { if (DBG > 0) fprintf (stderr, "%s.core_connect.bind: %s\n", prog_name, strerror (errno)); goto failure; } } s->myport = myport; } SYSCALL (CONNECT, result = connect (sd, (struct sockaddr *) sin, sizeof (*sin))); saved_err = errno; if (result == 0) { #ifdef HAVE_SSL if (s->ssl) core_ssl_connect (s); else #endif { s->state = S_CONNECTED; arg.l = 0; event_signal (EV_CONN_CONNECTED, (Object *) s, arg); } } else if (errno == EINPROGRESS) { /* The socket becomes writable only after the connection has been established. Hence we wait for writability to detect connection establishment. */ s->state = S_CONNECTING; interested_in_writing (s); if (param.timeout > 0.0) { arg.vp = s; assert (!s->watchdog); s->watchdog = timer_schedule (conn_timeout, arg, param.timeout); } } else { len = sizeof (async_errno); if (getsockopt (sd, SOL_SOCKET, SO_ERROR, &async_errno, &len) == 0 && async_errno != 0) errno = async_errno; saved_err = async_errno; if (DBG > 0) fprintf (stderr, "%s.core_connect.connect: %s (max_sd=%d)\n", prog_name, strerror (errno), max_sd); goto failure; } return 0; failure: conn_failure (s, saved_err); return -1; } int core_send (Conn *conn, Call *call) { Any_Type arg; arg.l = 0; event_signal (EV_CALL_ISSUE, (Object *) call, arg); call->conn = conn; /* NO refcounting here (see call.h). */ #ifdef UW_CALL_STATS if (param.call_stats > 0) { sprintf (call->id_hdr, "Client-Id: %d %d\r\n", param.client.id, (int) call->id); call_append_request_header (call, call->id_hdr, strlen(call->id_hdr)); } #endif /* UW_CALL_STATS */ if (param.no_host_hdr) { call->req.iov[IE_HOST].iov_base = (caddr_t) ""; call->req.iov[IE_HOST].iov_len = 0; } else if (!call->req.iov[IE_HOST].iov_base) { /* Default call's hostname to connection's hostname: */ call->req.iov[IE_HOST].iov_base = (caddr_t) conn->hostname; call->req.iov[IE_HOST].iov_len = conn->hostname_len; } /* NOTE: the protocol version indicates what the _client_ can understand. If we send HTTP/1.1, it doesn't mean that the server has to speak HTTP/1.1. In other words, sending an HTTP/1.1 header leaves it up to the server whether it wants to reply with a 1.0 or 1.1 reply. */ switch (call->req.version) { case 0x10000: if (param.no_host_hdr) { call->req.iov[IE_PROTL].iov_base = (caddr_t) http10req_nohost; call->req.iov[IE_PROTL].iov_len = sizeof (http10req_nohost) - 1; } else { call->req.iov[IE_PROTL].iov_base = (caddr_t) http10req; call->req.iov[IE_PROTL].iov_len = sizeof (http10req) - 1; } break; case 0x10001: if (param.no_host_hdr) { call->req.iov[IE_PROTL].iov_base = http11req_nohost; call->req.iov[IE_PROTL].iov_len = sizeof (http11req_nohost) - 1; } else { call->req.iov[IE_PROTL].iov_base = http11req; call->req.iov[IE_PROTL].iov_len = sizeof (http11req) - 1; } break; default: fprintf (stderr, "%s: unexpected version code %x\n", prog_name, call->req.version); exit (1); } call->req.iov_index = 0; call->req.iov_saved = call->req.iov[0]; /* insert call into connection's send queue: */ call_inc_ref (call); call->sendq_next = 0; if (!conn->sendq) { conn->sendq = conn->sendq_tail = call; arg.l = 0; event_signal (EV_CALL_SEND_START, (Object *) call, arg); if (conn->state >= S_CLOSING) return -1; #ifdef UW_DYNOUT if (call->timelimit != 0) { call->timeout = timer_now () + call->timelimit; } else { call->timeout = param.timeout ? timer_now () + param.timeout : 0.0; } #else call->timeout = param.timeout ? timer_now () + param.timeout : 0.0; #endif /* UW_DYNOUT */ interested_in_writing (conn); } else { conn->sendq_tail->sendq_next = call; conn->sendq_tail = call; } return 0; } void core_close (Conn *conn) { Call *call, *call_next; Any_Type arg; int sd; int prev_state = conn->state; struct linger linger; struct epoll_event evt; int epoll_op, rv; if (conn->state >= S_CLOSING) return; /* guard against recursive calls */ conn->state = S_CLOSING; if (DBG >= 10) fprintf (stderr, "%s.core_close(conn=%p)\n", prog_name, conn); if (conn->watchdog) { timer_cancel (conn->watchdog); conn->watchdog = 0; } /* first, get rid of all pending calls: */ for (call = conn->sendq; call; call = call_next) { call_next = call->sendq_next; call_dec_ref (call); } conn->sendq = 0; for (call = conn->recvq; call; call = call_next) { call_next = call->recvq_next; call_dec_ref (call); } conn->recvq = 0; #ifdef OLDWAY arg.l = 0; #else arg.i = prev_state; #endif event_signal (EV_CONN_CLOSE, (Object *) conn, arg); assert (conn->state == S_CLOSING); sd = conn->sd; conn->sd = -1; if (sd >=0 && conn->timed_out) { /* if we get a timeout sent a reset on a close * if --close-with-reset is used this has already been taken care of */ if (param.timeout_with_reset && !param.close_with_reset) { linger.l_onoff = 1; linger.l_linger = 0; if (DBG > 0) { printf("conn timed out setting up for reset\n"); } if (setsockopt (sd, SOL_SOCKET, SO_LINGER, &linger, sizeof (linger)) < 0) { fprintf (stderr, "%s.core_close.setsockopt(SO_LINGER): %s\n", prog_name, strerror (errno)); exit(1); } } } #ifdef HAVE_SSL if (conn->ssl) SSL_shutdown (conn->ssl); #endif if (sd >= 0) { /* if (conn->added_to_epoll) { evt.events = 0; evt.events = EPOLLIN | EPOLLOUT; evt.data.fd = sd; epoll_op = EPOLL_CTL_DEL ; SYSCALL (EPOLL_CTL, rv = epoll_ctl(epoll_fd, epoll_op, sd, &evt)); if (rv != 0) { fprintf (stderr, "%s: epoll_ctl failed on sd %d: %s\n", prog_name, sd, strerror(errno)); exit (1); } } */ close (sd); sd_to_conn[sd] = 0; BIG_FD_CLR (sd, &wrfds); BIG_FD_CLR (sd, &rdfds); } if (conn->myport > 0) port_put (conn->myport); /* A connection that has been closed is not useful anymore, so we give up the reference obtained when creating the session. This normally initiates destruction of the connection. */ conn_dec_ref (conn); } static void core_loop_handle_socket (int sd, int is_readable, int is_writable) { Conn *conn; int rc, async_errno; socklen_t len; Any_Type arg; /* only handle sockets that haven't timed out yet */ conn = sd_to_conn[sd]; if (!conn) { // fprintf(stderr, "core_loop_handle_socket: Conn became NULL!\n"); return; } conn_inc_ref (conn); /* Don't cancel this here just because we received some data. Wait for the whole chunk to arrive. if (conn->watchdog) { timer_cancel (conn->watchdog); conn->watchdog = 0; } */ if (conn->state == S_CONNECTING) { #ifdef HAVE_SSL if (conn->ssl) core_ssl_connect (conn); else #endif if (is_writable) { len = sizeof (async_errno); rc = getsockopt (sd, SOL_SOCKET, SO_ERROR, &async_errno, &len); if (rc < 0) { printf("%s: getsockopt failed\n", __FUNCTION__); perror("core_loop_handle_socket "); exit(1); } else if (async_errno == 0) { BIG_FD_CLR (sd, &wrfds); conn->state = S_CONNECTED; arg.l = 0; event_signal (EV_CONN_CONNECTED, (Object *) conn, arg); } else { // printf("%s: connect failed %s\n", __FUNCTION__, strerror(async_errno)); conn_failure(conn, async_errno); } } } else { if (is_writable && conn->sendq) do_send (conn); if (is_readable && conn->recvq) do_recv (conn); } conn_dec_ref (conn); } #ifdef HAVE_EPOLL static void core_loop_epoll (void) { int is_readable, is_writable, n, sd, i = 0; while (running) { TIME_BEGIN(); timer_tick (); TIME_END(timer_tick_time); TIME_BEGIN(); SYSCALL (EPOLL_WAIT, n = epoll_wait (epoll_fd, epoll_events, epoll_max_events, epoll_timeout)); if (n < 0) { fprintf (stderr, "%s.core_loop_epoll: epoll_wait failed: %s\n", prog_name, strerror (errno)); exit (1); } TIME_END(select_time); TIME_BEGIN(); ++iteration; for (i = 0; i < n; i++) { sd = epoll_events[i].data.fd; // fprintf(stderr, "fd = %d\n", sd); is_readable = is_writable = 0; if (epoll_events[i].events & EPOLLIN) is_readable = 1; if (epoll_events[i].events & EPOLLOUT) is_writable = 1; if (is_readable || is_writable) { core_loop_handle_socket (sd, is_readable, is_writable); if (n > 0) timer_tick (); } } TIME_END(work_time); } } #endif /* HAVE_EPOLL */ void core_loop_select (void) { int is_readable, is_writable, n, sd, bit, min_i, max_i, i = 0; big_fd_set readable, writable; fd_mask mask; while (running) { struct timeval tv = select_timeout; TIME_BEGIN(); timer_tick (); TIME_END(timer_tick_time); TIME_BEGIN(); readable = rdfds; writable = wrfds; min_i = min_sd / NFDBITS; max_i = max_sd / NFDBITS; SYSCALL (SELECT, n = select (max_sd + 1, &readable, &writable, 0, &tv)); if (n < 0) { fprintf (stderr, "%s.core_loop_select: select failed: %s\n", prog_name, strerror (errno)); exit (1); } TIME_END(select_time); TIME_BEGIN(); ++iteration; while (n > 0) { /* find the index of the fdmask that has something going on: */ do { ++i; if (i > max_i) i = min_i; assert (i <= max_i); mask = readable.fds_bits[i] | writable.fds_bits[i]; } while (!mask); bit = 0; sd = i*NFDBITS + bit; do { if (mask & 1) { --n; is_readable = (BIG_FD_ISSET (sd, &readable) && BIG_FD_ISSET (sd, &rdfds)); is_writable = (BIG_FD_ISSET (sd, &writable) && BIG_FD_ISSET (sd, &wrfds)); if (is_readable || is_writable) { core_loop_handle_socket (sd, is_readable, is_writable); if (n > 0) timer_tick (); } } mask = ((u_long) mask) >> 1; ++sd; } while (mask); } TIME_END(work_time); } /* while running */ } void core_loop (void) { #ifdef HAVE_EPOLL if (param.use_epoll) { core_loop_epoll(); } else { core_loop_select(); } #else core_loop_select(); #endif /* HAVE_EPOLL */ } void core_exit (void) { running = 0; printf ("Maximum connect burst length: %lu\n", max_burst_len); #ifdef TIME_SYSCALLS { u_int count; Time time; int i; printf ("Average syscall execution times:\n"); for (i = 0; i < NELEMS (syscall_name); ++i) { count = syscall_count[i]; time = syscall_time[i]; printf ("\t%s:\t%.3f ms/call (%.3fs total, %u calls)\n", syscall_name[i], count > 0 ? 1e3*time/count : 0, time, count); } putchar ('\n'); } #endif #ifdef TIME_CORE_LOOP { float iters = (float) iteration; printf ("Average time spent in stages of core loop:\n"); printf ("\ttimer_tick(): %.3f\n", 1000 * (timer_tick_time / iters)); printf ("\tselect() or epoll_wait(): %.3f\n", 1000 * (select_time / iters)); printf ("\twork: %.3f\n\n", 1000 * (work_time / iters)); } #endif } ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/core.h ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef core_h #define core_h #include #include #include #define __BIG_FD_SETSIZE 65535 #define __BIG_NFDBITS (8 * sizeof(unsigned long)) typedef struct { unsigned long fds_bits[__BIG_FD_SETSIZE / (8 * sizeof (unsigned long))]; } big_fd_set; void BIG_FD_CLR(int fd, big_fd_set *fdsetp); int BIG_FD_ISSET(int fd, big_fd_set *fdsetp); void BIG_FD_SET(int fd, big_fd_set *fdsetp); extern void core_init (void); extern struct sockaddr_in *core_addr_intern(const char *hostname, size_t hostname_len, int port); extern struct sockaddr_in *hash_lookup(const char *server, size_t server_len, int port); extern int core_connect (Conn *conn); extern int core_send (Conn *conn, Call *call); extern void core_close (Conn *conn); extern void core_loop (void); extern void core_exit (void); #endif /* core_h */ ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/core_connect ================================================ # This viminfo file was generated by Vim 7.4. # You may edit it if you're careful! # Value of 'encoding' when this file was written *encoding=utf-8 # hlsearch on (H) or off (h): ~h # Command Line History (newest to oldest): # Search String History (newest to oldest): # Expression History (newest to oldest): # Input Line History (newest to oldest): # Input Line History (newest to oldest): # Registers: # File marks: '0 1 0 ~/projects/benchmarking/media_streaming/sanity_httperf/httperf/grep # Jumplist (newest first): -' 1 0 ~/projects/benchmarking/media_streaming/sanity_httperf/httperf/grep # History of marks within files (newest to oldest): ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/event.c ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #define MAX_NUM_OPS 4 static const char * const event_name[EV_NUM_EVENT_TYPES] = { "EV_PERF_SAMPLE", "EV_HOSTNAME_LOOKUP_START", "EV_HOSTNAME_LOOKUP_STOP", "EV_SESS_NEW", "EV_SESS_FAILED", "EV_SESS_DESTROYED", "EV_CONN_NEW", "EV_CONN_CONNECTING", "EV_CONN_CONNECTED", "EV_CONN_CLOSE", "EV_CONN_DESTROYED", "EV_CONN_FAILED", "EV_CONN_TIMEOUT", "EV_CALL_NEW", "EV_CALL_ISSUE", "EV_CALL_SEND_START", "EV_CALL_SEND_RAW_DATA", "EV_CALL_SEND_STOP", "EV_CALL_RECV_START", "EV_CALL_RECV_HDR", "EV_CALL_RECV_RAW_DATA", "EV_CALL_RECV_DATA", "EV_CALL_RECV_FOOTER", "EV_CALL_RECV_STOP", "EV_CALL_DESTROYED", "EV_DUMP_STATS" }; typedef struct Event_Action { int num_ops; struct closure { Event_Handler op; Any_Type arg; } closure[MAX_NUM_OPS]; } Event_Action; static Event_Action action[EV_NUM_EVENT_TYPES] = {{0, }}; void event_register_handler (Event_Type et, Event_Handler handler, Any_Type arg) { struct closure *c; int n; n = action[et].num_ops; if (n >= MAX_NUM_OPS) { fprintf (stderr, "event_register_handler: sorry, attempted to register " "more than %d handlers\n", MAX_NUM_OPS); exit (1); } c = action[et].closure + n; c->op = handler; c->arg = arg; action[et].num_ops = n + 1; } void event_signal (Event_Type type, Object *obj, Any_Type arg) { Event_Action *act = action + type; struct closure *c, *end; if (DBG > 1) { assert (NELEMS (event_name) == EV_NUM_EVENT_TYPES); fprintf (stderr, "event_signal: %s (obj=%p,arg=%lx)\n", event_name[type], obj, arg.l); if (obj) { if (obj->type == OBJ_CALL) { Call *c = (Call *) obj; fprintf(stderr, "event_signal: current time %22.8lf timeout %22.8lf\n", timer_now_forced(), c->timeout); fprintf(stderr, "event_signal: send_start %22.8lf recv_start %22.8lf\n", c->basic.time_send_start, c->basic.time_recv_start); } } } end = &act->closure[act->num_ops]; for (c = &act->closure[0]; c < end; ++c) (*c->op) (type, obj, c->arg, arg); } ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/event.h ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef event_h #define event_h #include #include typedef enum Event_Type { EV_PERF_SAMPLE, EV_HOSTNAME_LOOKUP_START, EV_HOSTNAME_LOOKUP_STOP, EV_SESS_NEW, EV_SESS_FAILED, EV_SESS_DESTROYED, EV_CONN_NEW, EV_CONN_CONNECTING, EV_CONN_CONNECTED, EV_CONN_CLOSE, /* connection closed */ EV_CONN_DESTROYED, EV_CONN_FAILED, /* failed for reasons other than timeout */ EV_CONN_TIMEOUT, EV_CALL_NEW, EV_CALL_ISSUE, EV_CALL_SEND_START, EV_CALL_SEND_RAW_DATA, EV_CALL_SEND_STOP, EV_CALL_RECV_START, EV_CALL_RECV_HDR, EV_CALL_RECV_RAW_DATA, EV_CALL_RECV_DATA, EV_CALL_RECV_FOOTER, EV_CALL_RECV_STOP, EV_CALL_DESTROYED, EV_DUMP_STATS, EV_NUM_EVENT_TYPES } Event_Type; typedef struct Event { Event_Type type; Object *obj; Any_Type arg; } Event; typedef void (*Event_Handler) (Event_Type type, Object *obj, Any_Type registration_time_arg, Any_Type signal_time_arg); extern void event_register_handler (Event_Type et, Event_Handler handler, Any_Type arg); extern void event_signal (Event_Type type, Object *obj, Any_Type arg); #endif /* event_h */ ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/gen/Makefile ================================================ # Generated automatically from Makefile.in by configure. SHELL=/bin/sh srcdir = . top_srcdir = .. top_builddir = .. prefix = /usr/local bindir = ${exec_prefix}/bin mandir = ${prefix}/man CC = gcc RANLIB = ranlib INCLUDES = -I$(top_builddir) -I$(srcdir) -I$(top_srcdir) -I$(top_srcdir)/lib \ $(SSL_INCLUDES) -I/usr/kerberos/include DEFS = -DHAVE_CONFIG_H CPPFLAGS = -DNDEBUG -D_GNU_SOURCE -D_XOPEN_SOURCE CFLAGS = -g -O2 -Wall LDFLAGS = LIBS = -lssl -lcrypto -lm CPPFLAGS += -DBIG_FD_SETSIZE # Uncomment this to enable tracking statistics about each call (request) DEFS += -DUW_CALL_STATS # Uncomment this to enable session log file specified dynamic timeouts DEFS += -DUW_DYNOUT -DHAVE_EPOLL # Uncomment this to enable "pace_time" in wsesslog files DEFS += -DUW_PACE_REQUESTS COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -static -static-libgcc LINK = $(CC) $(LDFLAGS) -static -static-libgcc -o $@ .c.o: $(COMPILE) $< LIBGEN_OBJS = call_seq.o conn_rate.o misc.o rate.o session.o \ videosesslog.o sess_cookie.o # uri_fixed.o uri_wlog.o uri_wset.o \ # wsess.o wsesslog.o wsesspage.o \ # sess_cookie.o all: libgen.a libgen.a: $(LIBGEN_OBJS) ar r $@ $(LIBGEN_OBJS) $(RANLIB) $@ depend: install: clean: rm -f libgen.a $(LIBGEN_OBJS) distclean: clean rm -f *~ .PHONY: all install clean distclean depend ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/gen/Makefile.in ================================================ SHELL=/bin/sh VPATH = @srcdir@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ top_builddir = .. prefix = @prefix@ bindir = @bindir@ mandir = @mandir@ CC = @CC@ RANLIB = @RANLIB@ INCLUDES = -I$(top_builddir) -I$(srcdir) -I$(top_srcdir) -I$(top_srcdir)/lib \ $(SSL_INCLUDES) -I/usr/kerberos/include DEFS = @DEFS@ CPPFLAGS = @CPPFLAGS@ CFLAGS = @CFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ CPPFLAGS += -DBIG_FD_SETSIZE # Uncomment this to enable tracking statistics about each call (request) DEFS += -DUW_CALL_STATS # Uncomment this to enable session log file specified dynamic timeouts DEFS += -DUW_DYNOUT -DHAVE_EPOLL # Uncomment this to enable "pace_time" in wsesslog files DEFS += -DUW_PACE_REQUESTS COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -static -static-libgcc LINK = $(CC) $(LDFLAGS) -static -static-libgcc -o $@ @SET_MAKE@ .c.o: $(COMPILE) $< LIBGEN_OBJS = call_seq.o conn_rate.o misc.o rate.o session.o \ videosesslog.o sess_cookie.o # uri_fixed.o uri_wlog.o uri_wset.o \ # wsess.o wsesslog.o wsesspage.o \ # sess_cookie.o all: libgen.a libgen.a: $(LIBGEN_OBJS) ar r $@ $(LIBGEN_OBJS) $(RANLIB) $@ depend: install: clean: rm -f libgen.a $(LIBGEN_OBJS) distclean: clean rm -f *~ .PHONY: all install clean distclean depend ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/gen/call_seq.c ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Issue a sequence of calls on a connection. */ #include #include #include #include #include #include #define CONN_PRIVATE_DATA(c) \ ((Conn_Private_Data *) ((char *)(c) + conn_private_data_offset)) #define MIN(a,b) ((a) < (b) ? (a) : (b)) typedef struct Conn_Private_Data { int num_calls; int num_completed; int num_destroyed; } Conn_Private_Data; static size_t conn_private_data_offset; static void issue_calls (Conn *conn) { Conn_Private_Data *priv; Call *call; int i; priv = CONN_PRIVATE_DATA (conn); priv->num_completed = 0; priv->num_destroyed = 0; for (i = 0; i < param.burst_len; ++i) if (priv->num_calls++ < param.num_calls) { call = call_new (); if (call) { core_send (conn, call); call_dec_ref (call); } } } static void conn_connected (Event_Type et, Conn *conn) { assert (et == EV_CONN_CONNECTED && object_is_conn (conn)); issue_calls (conn); } static void call_done (Event_Type et, Call *call) { Conn *conn = call->conn; Conn_Private_Data *priv; assert (et == EV_CALL_RECV_STOP && conn && object_is_conn (conn)); priv = CONN_PRIVATE_DATA (conn); ++priv->num_completed; } static void call_destroyed (Event_Type et, Call *call) { Conn_Private_Data *priv; Conn *conn; assert (et == EV_CALL_DESTROYED && object_is_call (call)); conn = call->conn; priv = CONN_PRIVATE_DATA (conn); if (++priv->num_destroyed >= MIN (param.burst_len, param.num_calls)) { if (priv->num_completed == priv->num_destroyed && priv->num_calls < param.num_calls) issue_calls (conn); else core_close (conn); } } static void init (void) { Any_Type arg; conn_private_data_offset = object_expand (OBJ_CONN, sizeof (Conn_Private_Data)); arg.l = 0; event_register_handler (EV_CONN_CONNECTED, (Event_Handler) conn_connected, arg); event_register_handler (EV_CALL_RECV_STOP, (Event_Handler) call_done, arg); event_register_handler (EV_CALL_DESTROYED, (Event_Handler) call_destroyed, arg); } Load_Generator call_seq = { "performs a sequence of calls on a connection", init, no_op, no_op }; ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/gen/conn_rate.c ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Creates connections at the fixed rate PARAM.RATE or sequentially if PARAM.RATE is zero. */ #include #include #include #include #include #include #include #include static int num_conns_generated; static int num_conns_destroyed; static Rate_Generator rg; static int make_conn (Any_Type arg) { Conn *s; if (num_conns_generated++ >= param.num_conns) return -1; s = conn_new (); if (!s) return -1; core_connect (s); return 0; } static void destroyed (void) { if (++num_conns_destroyed >= param.num_conns) core_exit (); } static void init (void) { Any_Type arg; rg.arg.l = 0; rg.tick = make_conn; arg.l = 0; event_register_handler (EV_CONN_DESTROYED, (Event_Handler) destroyed, arg); } static void start (void) { rg.rate = ¶m.rate; rate_generator_start (&rg, EV_CONN_DESTROYED); } Load_Generator conn_rate = { "creates connections at a fixed rate", init, start, no_op }; ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/gen/misc.c ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Implements miscellaneous command-line specified operations. So far, the following options are implemented here: --add-header Adds one or more command-line specified header(s) to each call request. --method Sets the method to be used when performing a call. */ #include #include #include #include #include #include #include #include #include static const char *extra; static size_t extra_len; static size_t method_len; /* A simple module that collects cookies from the server responses and includes them in future calls to the server. */ static const char * unescape (const char *str, size_t *len) { char *dp, *dst = strdup (str); const char *cp; int ch; if (!dst) panic ("%s: strdup() failed: %s\n", prog_name, strerror (errno)); for (cp = str, dp = dst; (ch = *cp++); ) { if (ch == '\\') { ch = *cp++; switch (ch) { case '\\': /* \\ -> \ */ break; case 'a': /* \a -> LF */ ch = 10; break; case 'r': /* \r -> CR */ ch = 13; break; case 'n': /* \n -> CR/LF */ *dp++ = 13; ch = 10; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': ch = strtol (cp - 1, (char **) &cp, 8); break; default: fprintf (stderr, "%s: ignoring unknown escape sequence " "`\\%c' in --add-header\n", prog_name, ch); break; } } *dp++ = ch; } *len = dp - dst; return dst; } static void call_created (Event_Type et, Object *obj, Any_Type reg_arg, Any_Type arg) { Call *c = (Call *) obj; assert (et == EV_CALL_NEW && object_is_call (obj)); if (method_len > 0) call_set_method (c, param.method, method_len); if (extra_len > 0) call_append_request_header (c, extra, extra_len); } static void init (void) { Any_Type arg; if (param.additional_header) extra = unescape (param.additional_header, &extra_len); if (param.method) method_len = strlen (param.method); arg.l = 0; event_register_handler (EV_CALL_NEW, call_created, arg); } Load_Generator misc = { "Miscellaneous command line options", init, no_op, no_op }; ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/gen/rate.c ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #ifndef SRINI_RATE int current_rate = 0; Time duration_in_current_rate = 0; #endif /* By pushing the random number generator state into the caller via the xsubi array below, we gain some test repeatability. For example, let us say one generator was starting sessions, and a different generator was controlling requests within a session. If both processes were sharing the same random number generator, then a premature session termination would change the subsequent session arrival spacing. */ static Time next_arrival_time_det (Rate_Generator *rg) { return rg->rate->mean_iat; } static Time next_arrival_time_uniform (Rate_Generator *rg) { Time lower, upper; lower = rg->rate->min_iat; upper = rg->rate->max_iat; return lower + (upper - lower)*erand48 (rg->xsubi); } static Time next_arrival_time_exp (Rate_Generator *rg) { Time mean = rg->rate->mean_iat; return -mean*log (1.0 - erand48 (rg->xsubi)); } #ifndef SRINI_RATE static Time next_arrival_time_variable (Rate_Generator *rg) { Time next; next = rg->rate->iat[current_rate]; duration_in_current_rate += next; if (duration_in_current_rate >= rg->rate->duration[current_rate]) { current_rate ++; if (current_rate >= rg->rate->numRates) current_rate = 0; duration_in_current_rate = 0; } return (next); } /* variable interarrival times, using an exponential distribution */ static Time next_arrival_time_variable_exp (Rate_Generator *rg) { Time next; /* compute exponentially distributed arrival time */ next = -(rg->rate->iat[current_rate]) * log (1.0 - erand48 (rg->xsubi)); duration_in_current_rate += next; /* if we've spent enough time at this rate, continue with the next */ /* or start again from the first rate/duration pair. */ if (duration_in_current_rate >= rg->rate->duration[current_rate]) { current_rate ++; if (current_rate >= rg->rate->numRates) current_rate = 0; duration_in_current_rate = 0; } return (next); } #endif static void tick (Timer *t, Any_Type arg) { Time delay, now = timer_now (); Rate_Generator *rg = arg.vp; rg->timer = 0; if (rg->done) return; while (now > rg->next_time) { delay = (*rg->next_interarrival_time) (rg); if (verbose > 2) fprintf (stderr, "next arrival delay = %.4f\n", delay); rg->next_time += delay; rg->done = ((*rg->tick) (rg->arg) < 0); if (rg->done) return; } rg->timer = timer_schedule ((Timer_Callback) tick, arg, rg->next_time - now); } static void done (Event_Type type, Object *obj, Any_Type reg_arg, Any_Type call_arg) { Rate_Generator *rg = reg_arg.vp; if (rg->done) return; rg->done = ((*rg->tick) (rg->arg) < 0); } void rate_generator_start (Rate_Generator *rg, Event_Type completion_event) { Time (*func) (struct Rate_Generator *rg); Any_Type arg; Time delay; /* Initialize random number generator with the init values here, all rate generators (although independent) will follow the same sequence of random values. We factor in the client's id to make sure no two machines running httperf generate identical random numbers. May want to pass these values as args to rate_generator_start in the future. */ rg->xsubi[0] = 0x1234 ^ param.client.id; rg->xsubi[1] = 0x5678 ^ (param.client.id << 8); rg->xsubi[2] = 0x9abc ^ ~param.client.id; arg.vp = rg; if (rg->rate->rate_param > 0.0) { switch (rg->rate->dist) { case DETERMINISTIC: func = next_arrival_time_det; break; case UNIFORM: func = next_arrival_time_uniform; break; case EXPONENTIAL: func = next_arrival_time_exp; break; #ifndef SRINI_RATE case VARIABLE: func = next_arrival_time_variable; break; case VARIABLE_EXP: func = next_arrival_time_variable_exp; break; #endif default: fprintf (stderr, "%s: unrecognized interarrival distribution %d\n", prog_name, rg->rate->dist); exit (-1); } rg->next_interarrival_time = func; delay = (*func) (rg); /* stagger the client starts by adding an initial delay */ if (param.client.stagger_start) { printf( "stagger start for client %d/%d by: %.5f\n", param.client.id, param.client.num_clients, (double) param.client.id / param.client.num_clients / rg->rate->rate_param ); delay += (double) param.client.id / param.client.num_clients / rg->rate->rate_param; } /* bias `next time' so that timeouts are rounded to the closest tick: */ rg->next_time = timer_now () + delay; rg->timer = timer_schedule ((Timer_Callback) tick, arg, delay); } else /* generate callbacks sequentially: */ event_register_handler (completion_event, done, arg); rg->start = timer_now (); rg->done = ((*rg->tick) (rg->arg) < 0); } void rate_generator_stop (Rate_Generator *rg) { if (rg->timer) { timer_cancel (rg->timer); rg->timer = 0; } rg->done = 1; } ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/gen/rate.h ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef rate_h #define rate_h #include #include typedef struct Rate_Generator { u_short xsubi[3]; /* used for random number generation */ Rate_Info *rate; Time start; Time next_time; Any_Type arg; Timer *timer; int (*tick) (Any_Type arg); int done; Time (*next_interarrival_time) (struct Rate_Generator *rg); } Rate_Generator; extern void rate_generator_start (Rate_Generator *rg, Event_Type completion_event); extern void rate_generator_stop (Rate_Generator *rg); #endif /* rate_h */ ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/gen/sess_cookie.c ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* This module intercepts `Set-Cookie:' headers on a per-session basis and includes set cookies in future calls of the session. Missing features: - intercepted cookies are always sent, independent of any constraints that may be present in the set-cookie header */ #include #include #include #include #include #include #include #include #include #include #include #include #define MAX_COOKIE_LEN 256 #define SESS_PRIVATE_DATA(c) \ ((Sess_Private_Data *) ((char *)(c) + sess_private_data_offset)) #define CALL_PRIVATE_DATA(c) \ ((Call_Private_Data *) ((char *)(c) + call_private_data_offset)) typedef struct Sess_Private_Data { /* For now, we support just one cookie per session. If we get more than one cookie, we'll print a warning message when --debug is turned on. */ size_t cookie_len; /* We can't malloc the cookie string because we may get a ``Set-Cookie:'' while there are calls pending that refer to an existing cookie. So if we were to malloc & free cookies, we would have to use reference counting to avoid the risk of dangling pointers. */ char cookie[MAX_COOKIE_LEN]; } Sess_Private_Data; /* We need the call private data to ensure that the cookie gets set only once. EV_CALL_ISSUE gets signalled each time a call is sent on a connection. Since a connection may fail, the same call may be issued multiple times, hence we need to make sure that the cookie gets set only once per call. */ typedef struct Call_Private_Data { u_int cookie_present; /* non-zero if cookie has been set already */ char cookie[MAX_COOKIE_LEN]; } Call_Private_Data; static size_t sess_private_data_offset = -1; static size_t call_private_data_offset = -1; /* A simple module that collects cookies from the server responses and includes them in future calls to the server. */ static void call_issue (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { Call_Private_Data *cpriv; Sess_Private_Data *priv; Sess *sess; Call *call; assert (et == EV_CALL_ISSUE && object_is_call (obj)); call = (Call *) obj; cpriv = CALL_PRIVATE_DATA (call); if (cpriv->cookie_present) /* don't do anything if cookie has been set already */ return; sess = session_get_sess_from_call (call); priv = SESS_PRIVATE_DATA (sess); if (priv->cookie_len > 0) { if (DBG > 1) fprintf (stderr, "call_issue.%ld: inserting `%s'\n", call->id, priv->cookie); cpriv->cookie_present = 1; memcpy (cpriv->cookie, priv->cookie, priv->cookie_len + 1); call_append_request_header (call, cpriv->cookie, priv->cookie_len); } } static void call_recv_hdr (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { char *hdr, *start, *end; Sess_Private_Data *priv; size_t len; struct iovec *line; Sess *sess; Call *call; assert (et == EV_CALL_RECV_HDR && object_is_call (obj)); call = (Call *) obj; sess = session_get_sess_from_call (call); priv = SESS_PRIVATE_DATA (sess); line = callarg.vp; hdr = line->iov_base; if (tolower (hdr[0]) == 's' && line->iov_len > 12 && strncasecmp (hdr + 1, "et-cookie: ", 11) == 0) { /* munch time! */ start = hdr + 12; end = strchr (start, ';'); if (!end) end = hdr + line->iov_len; len = end - start; if (DBG > 0 && priv->cookie_len > 0) fprintf (stderr, "%s: can't handle more than one " "cookie at a time, replacing existing one\n", prog_name); if (len + 10 >= MAX_COOKIE_LEN) { fprintf (stderr, "%s.sess_cookie: truncating cookie to %d bytes\n", prog_name, MAX_COOKIE_LEN - 11); len = MAX_COOKIE_LEN - 11; } memcpy (priv->cookie, "Cookie: ", 8); memcpy (priv->cookie + 8, start, len); memcpy (priv->cookie + 8 + len, "\r\n", 2); priv->cookie[10 + len] = '\0'; priv->cookie_len = len + 10; if (DBG > 0) fprintf (stderr, "%s: got cookie `%s'\n", prog_name, start); } } static void init (void) { Any_Type arg; sess_private_data_offset = object_expand (OBJ_SESS, sizeof (Sess_Private_Data)); call_private_data_offset = object_expand (OBJ_CALL, sizeof (Call_Private_Data)); arg.l = 0; event_register_handler (EV_CALL_ISSUE, call_issue, arg); event_register_handler (EV_CALL_RECV_HDR, call_recv_hdr, arg); } Load_Generator sess_cookie = { "per-session cookie manager", init, no_op, no_op }; ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/gen/session.c ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* A session consists of a number of calls. Workload generators such as wsess and wsesslog determine when and how to issue calls. This module is responsible for the actual mechanics of issuing the calls. This includes creating and managing connections as necessary. Connection management can be controlled by command-line options --max-piped-calls=Np and --max-connections=Nc. This module creates up to Nc concurrent connections to dispatch calls. On each connection, up to Np pipelined requests can be issued. When no more calls can be issued, this module waits until some of the pending calls complete. Note that HTTP/1.1 allows a server to close a connection pretty much any time it feels like. This means that a session may fail (be closed) while there pipelined calls are pending. In such a case, this module takes care of creating a new connection and re-issuing the calls that were pending on the failed connection. A session is considered to fail if: (a) any operation exceeds the timeout parameters, or (b) a connection closes on us before we received at least one reply, or (c) param.failure_status is non-zero and the reply status of a call matches this failure status. */ #include #include #include #include #include #include #include #include #include #include #include #define MAX_CONN 4 /* max # of connections per session */ #define MAX_PIPED 32 /* max # of calls that can be piped */ #define SESS_PRIVATE_DATA(c) \ ((Sess_Private_Data *) ((char *)(c) + sess_private_data_offset)) #define CONN_PRIVATE_DATA(c) \ ((Conn_Private_Data *) ((char *)(c) + conn_private_data_offset)) #define CALL_PRIVATE_DATA(c) \ ((Call_Private_Data *) ((char *)(c) + call_private_data_offset)) typedef struct Sess_Private_Data { struct Conn_Info { Conn *conn; /* connection or NULL */ u_int is_connected : 1; /* is connection ready for use? */ u_int is_successful : 1; /* got at least one reply on this conn? */ /* Ring-buffer of pending calls: */ u_int num_pending; /* # of calls pending */ u_int num_sent; /* # of calls sent so far */ u_int rd; /* first pending call */ u_int wr; /* where to insert next call */ Call *call[MAX_PIPED]; } conn_info[MAX_CONN]; } Sess_Private_Data; typedef struct Conn_Private_Data { Sess *sess; struct Conn_Info *ci; /* pointer to relevant conn-info */ } Conn_Private_Data; typedef struct Call_Private_Data { Sess *sess; } Call_Private_Data; static size_t sess_private_data_offset = -1; static size_t conn_private_data_offset = -1; static size_t call_private_data_offset = -1; static size_t max_qlen; static void create_conn (Sess *sess, struct Conn_Info *ci) { Conn_Private_Data *cpriv; Sess_Private_Data *spriv; /* No connection yet (or anymore). Create a new connection. Note that CI->CONN is NOT reference-counted. This is again to avoid introducing recursive dependencies (see also comment regarding member CONN in call.h). */ ci->conn = conn_new (); if (!ci->conn) { sess_failure (sess); return; } ci->conn->basic.num_calls = sess->num_requests; cpriv = CONN_PRIVATE_DATA (ci->conn); spriv = SESS_PRIVATE_DATA (sess); cpriv->sess = sess; cpriv->ci = ci; ci->is_connected = 0; ci->is_successful = 0; ci->num_sent = 0; /* (re-)send all pending calls */ // strcpy(ci->conn->local_ip, spriv->local_ip); if (sess->port != 0) { ci->conn->port = sess->port; } if (sess->server != NULL) { ci->conn->hostname = sess->server; ci->conn->hostname_len = strlen(sess->server); } #ifdef HAVE_SSL /* Add SSL set-up for wsesslog file specified SSL sessions */ if (sess->use_ssl == 1 && !ci->conn->ssl) { ci->conn->ssl = SSL_new (ssl_ctx); if (!ci->conn->ssl) { ERR_print_errors_fp (stderr); exit (-1); } if (param.ssl_cipher_list) { /* set order of ciphers */ int ssl_err = SSL_set_cipher_list (ci->conn->ssl, param.ssl_cipher_list); if (DBG > 2) fprintf (stderr, "core_ssl_connect: set_cipher_list returned %d\n", ssl_err); } } /* Remove SSL set-up for wsesslog file specified SSL sessions */ else if (sess->use_ssl == 2 && ci->conn->ssl) { SSL_free(ci->conn->ssl); ci->conn->ssl = NULL; } if (param.ssl_reuse && ci->conn->ssl && sess->ssl) { if (DBG > 0) fprintf (stderr, "create_conn: reusing SSL session %p\n", (void *) sess->ssl); SSL_copy_session_id (ci->conn->ssl, sess->ssl); } #endif strcpy(ci->conn->local_ip, sess->local_ip); ci->conn->log_index = sess->log_index; if (core_connect (ci->conn) < 0) sess_failure (sess); } static void send_calls (Sess *sess, struct Conn_Info *ci) { u_int rd; int i; if (!ci->conn) { create_conn (sess, ci); return; } if (!ci->is_connected) /* wait until connection is connected (or has failed) */ return; rd = (ci->rd + ci->num_sent) % MAX_PIPED; for (i = ci->num_sent; i < ci->num_pending; ++i) { core_send (ci->conn, ci->call[rd]); ++ci->num_sent; rd = (rd + 1) % MAX_PIPED; } } static void sess_destroyed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { Sess_Private_Data *priv; struct Conn_Info *ci; Sess *sess; int i, j, rd; assert (et == EV_SESS_DESTROYED && object_is_sess (obj)); sess = (Sess *) obj; priv = SESS_PRIVATE_DATA (sess); for (i = 0; i < param.max_conns; ++i) { ci = priv->conn_info + i; if (ci->conn) core_close (ci->conn); rd = ci->rd; for (j = 0; j < ci->num_pending; ++j) { call_dec_ref (ci->call[rd]); rd = (rd + 1) % MAX_PIPED; } } } static void conn_connected (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { Conn_Private_Data *cpriv; struct Conn_Info *ci; Sess *sess; Conn *conn; assert (et == EV_CONN_CONNECTED && object_is_conn (obj)); conn = (Conn *) obj; cpriv = CONN_PRIVATE_DATA (conn); sess = cpriv->sess; ci = cpriv->ci; ci->is_connected = 1; #ifdef HAVE_SSL if (param.ssl_reuse && !sess->ssl && ci->conn->ssl) { sess->ssl = SSL_dup (ci->conn->ssl); if (DBG > 0) fprintf (stderr, "create_conn: cached SSL session %p as %p\n", (void *) ci->conn->ssl, (void *) sess->ssl); } #endif /* HAVE_SSL */ send_calls (sess, ci); } static void conn_failed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { Conn_Private_Data *cpriv; struct Conn_Info *ci; Conn *conn; Sess *sess; assert (et == EV_CONN_FAILED && object_is_conn (obj)); conn = (Conn *) obj; cpriv = CONN_PRIVATE_DATA (conn); sess = cpriv->sess; ci = cpriv->ci; if (ci->is_successful || param.retry_on_failure) { /* try to create a new connection so we can issue the remaining calls. */ create_conn (sess, ci); } else { /* The connection failed before we got even one reply, so declare the session as dead... */ sess_failure (cpriv->sess); } } static void conn_timeout (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { Conn_Private_Data *cpriv; Conn *conn; /* doh, this session is dead now... */ assert (et == EV_CONN_TIMEOUT && object_is_conn (obj)); conn = (Conn *) obj; cpriv = CONN_PRIVATE_DATA (conn); sess_failure (cpriv->sess); } static void call_done (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { Conn_Private_Data *cpriv; struct Conn_Info *ci; Sess *sess; Conn *conn; Call *call; assert (et == EV_CALL_RECV_STOP && object_is_call (obj)); call = (Call *) obj; conn = call->conn; cpriv = CONN_PRIVATE_DATA (conn); sess = cpriv->sess; ci = cpriv->ci; if (conn->watchdog) { timer_cancel (conn->watchdog); conn->watchdog = 0; } ci->is_successful = 1; /* conn has received at least one reply */ /* remove the call from the conn_info structure */ assert (ci->call[ci->rd] == call && ci->num_pending > 0 && ci->num_sent > 0); ci->call[ci->rd] = 0; ci->rd = (ci->rd + 1) % MAX_PIPED; --ci->num_pending; --ci->num_sent; /* if the reply status matches the failure status, the session has failed */ if (param.failure_status && call->reply.status == param.failure_status) { if (param.retry_on_failure) session_issue_call (sess, call); else sess_failure (sess); } call_dec_ref (call); if (call->req.version < 0x10001) { /* Rather than waiting for the connection to close on us, we close it pro-actively (this is what a pre-1.1 browser would do. */ core_close (ci->conn); ci->conn = 0; } } void session_init (void) { Any_Type arg; if (!param.max_conns) param.max_conns = MAX_CONN; if (!param.max_piped) { #ifdef OLDWAY if (param.http_version >= 0x10001) param.max_piped = MAX_PIPED; else /* no pipelining before HTTP/1.1... */ param.max_piped = 1; #else param.max_piped = MAX_PIPED; #endif } if (param.max_conns > MAX_CONN) { fprintf (stderr, "%s.session_init: --max-conns must be <= %u\n", prog_name, MAX_CONN); exit (1); } if (param.max_piped > MAX_PIPED) { fprintf (stderr, "%s.session_init: --max-piped-calls must be <= %u\n", prog_name, MAX_PIPED); exit (1); } max_qlen = param.max_conns * param.max_piped; sess_private_data_offset = object_expand (OBJ_SESS, sizeof (Sess_Private_Data)); conn_private_data_offset = object_expand (OBJ_CONN, sizeof (Conn_Private_Data)); call_private_data_offset = object_expand (OBJ_CALL, sizeof (Call_Private_Data)); arg.l = 0; event_register_handler (EV_SESS_DESTROYED, sess_destroyed, arg); event_register_handler (EV_CONN_CONNECTED, conn_connected, arg); event_register_handler (EV_CONN_FAILED, conn_failed, arg); event_register_handler (EV_CONN_TIMEOUT, conn_timeout, arg); event_register_handler (EV_CALL_RECV_STOP, call_done, arg); } size_t session_max_qlen (Sess *sess) { return max_qlen; } size_t session_current_qlen (Sess *sess) { Sess_Private_Data *priv; size_t num_pending = 0; int i; priv = SESS_PRIVATE_DATA (sess); for (i = 0; i < param.max_conns; ++i) num_pending += priv->conn_info[i].num_pending; return num_pending; } int session_issue_call (Sess *sess, Call *call) { Call_Private_Data *cpriv; Sess_Private_Data *priv; struct Conn_Info *ci; int i; priv = SESS_PRIVATE_DATA (sess); cpriv = CALL_PRIVATE_DATA (call); cpriv->sess = sess; for (i = 0; i < param.max_conns; ++i) { ci = priv->conn_info + i; if (ci->num_pending < param.max_piped) { ++ci->num_pending; ci->call[ci->wr] = call; call_inc_ref (call); ci->wr = (ci->wr + 1) % MAX_PIPED; send_calls (sess, ci); return 0; } } fprintf (stderr, "%s.session_issue_call: too many calls pending!\n" "\tIncrease --max-connections and/or --max-piped-calls.\n", prog_name); exit (1); } Sess * session_get_sess_from_conn (Conn *conn) { assert (object_is_conn (conn)); return CONN_PRIVATE_DATA (conn)->sess; } Sess * session_get_sess_from_call (Call *call) { assert (object_is_call (call)); return CALL_PRIVATE_DATA (call)->sess; } Call * session_get_last_call (Conn *conn) { assert (object_is_conn(conn)); Call *c; struct Conn_Info *ci; int index; ci = CONN_PRIVATE_DATA(conn)->ci; assert (ci != NULL); index = (ci->wr-1) % MAX_PIPED; c = ci->call[index]; assert (c != NULL); return c; } ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/gen/session.h ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef session_h #define session_h #include extern void session_init (void); /* initialize session module */ /* Maximum number of calls that can be queued on a session. */ extern size_t session_max_qlen (Sess *sess); /* Current number of calls that are queued on the session. */ extern size_t session_current_qlen (Sess *sess); /* Issue call CALL on session SESS. Returns negative number in case of failure. */ extern int session_issue_call (Sess *sess, Call *call); /* Given a connection object, find the session object that the connection belongs to. */ extern Sess *session_get_sess_from_conn (Conn *conn); /* Given a call object, find the session object that the call belongs to. */ extern Sess *session_get_sess_from_call (Call *call); /* Given a connection object, return last call that was added * to the connection. This is used by call_stats when a * connection times out before the connection is established */ extern Call *session_get_last_call (Conn *conn); #endif /* session_h */ ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/gen/uri_fixed.c ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Causes calls to make a request to the fixed URI specified by PARAM.URI. */ #include #include #include #include #include #include static size_t uri_len; static void set_uri (Event_Type et, Call *call) { assert (et == EV_CALL_NEW && object_is_call (call)); call_set_uri (call, param.uri, uri_len); } static void init (void) { Any_Type arg; uri_len = strlen (param.uri); arg.l = 0; event_register_handler (EV_CALL_NEW, (Event_Handler) set_uri, arg); } Load_Generator uri_fixed = { "fixed url", init, no_op, no_op }; ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/gen/uri_wlog.c ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by Stephane Eranian This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* This load generator can be used to recreate a workload based on a server log file. This module can be used in conjunction with two comands to help in extracting information from the httpd CLF file (contact eranian@hpl.hp.com). Please note that you don't necessary need any of those tools. You can recreate the list of URIs by hand or with any other programs as long as you respect the format expected by this module (and also provided than you have the corresponding document tree on the server side). The format of the file used by this module is very simple (maybe too simple): URI1\0URI2\0......URIn\0 It is a simple concatenated list of URI separated by the \0 (end of string) marker. This way, we don't need any parsing of the string when generating the URI. You can choose to loop on te list of URIs by using the following command line option to httperf: % httperf .... --wlog y,my_uri_file Otherwise httperf will stop once it reaches the end of the list. Any comment on this module contact eranian@hpl.hp.com or davidm@hpl.hp.com. */ #include #include #include #include #include #include #include #if __APPLE__ // There is a bug on MAC OS X where unistd.h and stdlib.h both declare // the same thing and this generates warnings/errors with -Werror // #include int close(int fd); #else #include #endif #include #include #include #include #include #include static char *fbase, *fend, *fcurrent; static void set_uri (Event_Type et, Call * c) { int len, did_wrap = 0; const char *uri; assert (et == EV_CALL_NEW && object_is_call (c)); do { if (fcurrent >= fend) { if (did_wrap) panic ("%s: %s does not contain any valid URIs\n", prog_name, param.wlog.file); did_wrap = 1; /* We reached the end of the uri list so wrap around to the beginning. If not looping, also ask for the test to stop as soon as possible (the current request will still go out, but httperf won't wait for its reply to show up). */ fcurrent = fbase; if (!param.wlog.do_loop) core_exit (); } uri = fcurrent; len = strlen (fcurrent); call_set_uri (c, uri, len); fcurrent += len + 1; } while (len == 0); if (verbose) printf ("%s: accessing URI `%s'\n", prog_name, uri); } void init_wlog (void) { struct stat st; Any_Type arg; int fd; #ifdef UW_CALL_STATS if (param.call_stats >= 0) { fprintf(stderr, "Can not use --call-stats with --wlog\n"); exit(1); } #endif /* UW_CALL_STATS */ fd = open (param.wlog.file, O_RDONLY, 0); if (fd == -1) panic ("%s: can't open %s\n", prog_name, param.wlog.file); fstat (fd, &st); if (st.st_size == 0) panic ("%s: file %s is empty\n", prog_name, param.wlog.file); /* mmap anywhere in address space: */ fbase = (char *) mmap (0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (fbase == (char *) 0 - 1) panic ("%s: can't mmap the file: %s\n", prog_name, strerror (errno)); close (fd); /* set the upper boundary: */ fend = fbase + st.st_size; /* set current entry: */ fcurrent = fbase; arg.l = 0; event_register_handler (EV_CALL_NEW, (Event_Handler) set_uri, arg); } static void stop_wlog (void) { munmap (fbase, fend - fbase); } Load_Generator uri_wlog = { "Generates URIs based on a predetermined list", init_wlog, no_op, stop_wlog }; ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/gen/uri_wset.c ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Causes accesses to a fixed set of files (working set) in such a way that is likely to cause disk I/O with a certain probability. */ #include #include #include #include #include #include #include #define MAX_URI_LEN 128 #define CALL_PRIVATE_DATA(c) \ ((void *) ((char *)(c) + call_private_data_offset)) static double miss_prob; static unsigned file_num; static size_t call_private_data_offset; static size_t uri_prefix_len; static void set_uri (Event_Type et, Call *c) { char *cp, *buf_end; unsigned j, n; assert (et == EV_CALL_NEW && object_is_call (c)); miss_prob += param.wset.target_miss_rate; if (miss_prob >= 1.0) { /* generate (what we hope to be) a miss */ miss_prob -= 1.0; file_num += param.client.num_clients; if (file_num >= param.wset.num_files) file_num -= param.wset.num_files; } /* fill in extension: */ buf_end = (char *) CALL_PRIVATE_DATA (c) + MAX_URI_LEN; cp = buf_end - 6; memcpy (cp, ".html", 6); /* fill in file & pathname: */ n = file_num; for (j = 1; j < param.wset.num_files; j *= 10, n /= 10) { cp -= 2; cp[0] = '/'; cp[1] = '0' + (n % 10); } /* fill in the uri prefix specified by param.uri: */ cp -= uri_prefix_len; if (cp < (char *) CALL_PRIVATE_DATA (c)) { fprintf (stderr, "%s.uri_wset: URI buffer overflow!\n", prog_name); exit (1); } memcpy (cp, param.uri, uri_prefix_len); call_set_uri (c, cp, (buf_end - cp) - 1); if (verbose) printf ("%s: accessing URI `%s'\n", prog_name, cp); } static void init (void) { Any_Type arg; #ifdef UW_CALL_STATS if (param.call_stats >= 0) { fprintf(stderr, "Can not use --call-stats with --wset\n"); exit(1); } #endif /* UW_CALL_STATS */ miss_prob = drand48 (); file_num = param.client.id; call_private_data_offset = object_expand (OBJ_CALL, MAX_URI_LEN); uri_prefix_len = strlen (param.uri); if (param.uri[uri_prefix_len - 1] == '/') { ++param.uri; --uri_prefix_len; } arg.l = 0; event_register_handler (EV_CALL_NEW, (Event_Handler) set_uri, arg); } Load_Generator uri_wset = { "Generates URIs accessing a working-set at a given rate", init, no_op, no_op }; ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/gen/videosesslog.c ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by Richard Carter This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Creates sessions at the fixed rate PARAM.RATE. The session descriptions are read in from a configuration file. There is currently no tool that translates from standard log formats to the format accepted by this module. An example input file follows: # # This file specifies the potentially-bursty uri sequence for a number of # user sessions. The format rules of this file are as follows: # # Comment lines start with a '#' as the first character. # anywhere else # is considered part of the uri. # # Lines with only whitespace delimit session definitions (multiple blank # lines do not generate "null" sessions). # # Lines otherwise specify a uri-sequence (1 uri per line). If the # first character of the line is whitespace (e.g. space or tab), the # uri is considered to be part of a burst that is sent out after the # previous non-burst uri. # # session 1 definition (this is a comment) /foo.html /pict1.gif /pict2.gif /foo2.html /pict3.gif /pict4.gif #session 2 definition /foo3.html /foo4.html /pict5.gif Any comment on this module contact carter@hpl.hp.com. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef UW_PACE_REQUESTS /* declare function defined in stat/call_stats.c */ double get_call_total_conn_time( Call *c ); #endif /* UW_PACE_REQUESTS */ /* Changes involved in adding headers to individual requests will be surrouned * by #ifdef WSESSLOG_HEADERS ... #endif */ #define WSESSLOG_HEADERS /* Maximum number of sessions that can be defined in the configuration file. */ #define MAX_SESSION_TEMPLATES 250000 #ifndef TRUE #define TRUE (1) #endif #ifndef FALSE #define FALSE (0) #endif #define SESS_PRIVATE_DATA(c) \ ((Sess_Private_Data *) ((char *)(c) + sess_private_data_offset)) typedef struct req REQ; struct req { REQ *next; int method; char *uri; int uri_len; char *cookie; int cookie_len; char *contents; int contents_len; #ifdef WSESSLOG_HEADERS char extra_hdrs[16384]; /* plenty for "Content-length: 1234567890" + custom headers */ #else char extra_hdrs[50]; /* plenty for "Content-length: 1234567890" */ #endif /* WSESSLOG_HEADERS */ int extra_hdrs_len; #ifdef UW_DYNOUT int timelimit; #endif /* UW_DYNOUT */ /* These fields are used for call stats only */ int file_size; }; typedef struct burst BURST; struct burst { BURST *next; int num_reqs; Time user_think_time; #ifdef UW_PACE_REQUESTS int pace_requests; #endif /* UW_PACE_REQUESTS */ REQ *req_list; }; typedef struct Sess_Private_Data Sess_Private_Data; struct Sess_Private_Data { u_int num_calls_in_this_burst; /* # of calls created for this burst */ u_int num_calls_target; /* total # of calls desired */ u_int num_calls_destroyed; /* # of calls destroyed so far */ Timer *timer; /* timer for session think time */ int total_num_reqs; /* total number of requests in this session */ int http_version; /* HTTP version number */ BURST *current_burst; /* the current burst we're working on */ REQ *current_req; /* the current request we're working on */ int port; /* specifies port used for this session, 0 => use default */ const char *server; /* specifies server used for this session, NULL => use default */ #ifdef HAVE_SSL int use_ssl; /* 1 = use ssl, 2 = don't use ssl, other = default*/ #endif /* HAVE_SSL */ /* these fields are used for call stats only */ REQ *cur_missed_req; BURST *cur_missed_bur; REQ *prv_missed_req; char local_ip[16]; }; typedef struct Session_Log_Desc Session_Log_Desc; struct Session_Log_Desc { Sess_Private_Data session_templates[MAX_SESSION_TEMPLATES]; int num_templates; int next_session_template; }; static Session_Log_Desc* session_logs; /* Methods allowed for a request: */ enum { HM_DELETE, HM_GET, HM_HEAD, HM_OPTIONS, HM_POST, HM_PUT, HM_TRACE, HM_LEN }; static const char *call_method_name[] = { "DELETE", "GET", "HEAD", "OPTIONS", "POST", "PUT", "TRACE" }; double* request_mix_cdf = NULL; static size_t sess_private_data_offset; static int num_sessions_generated; static int num_sessions_destroyed; static Rate_Generator rg_sess; static void sess_destroyed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { Sess_Private_Data *priv; Sess *sess; assert (et == EV_SESS_DESTROYED && object_is_sess (obj)); sess = (Sess *) obj; priv = SESS_PRIVATE_DATA (sess); if (priv->timer) { timer_cancel (priv->timer); priv->timer = 0; } if (++num_sessions_destroyed >= param.num_sessions) core_exit (); } static void issue_calls (Sess *sess, Sess_Private_Data *priv) { int i, to_create, retval, n; const char *method_str; Call *call; REQ *req; /* Mimic browser behavior of fetching html object, then a couple of embedded objects: */ to_create = 1; if (priv->num_calls_in_this_burst > 0) { to_create = priv->current_burst->num_reqs - priv->num_calls_in_this_burst; } n = session_max_qlen (sess) - session_current_qlen (sess); if (n < to_create) { to_create = n; } priv->num_calls_in_this_burst += to_create; for (i = 0; i < to_create; ++i) { call = call_new (); if (!call) { sess_failure (sess); return; } /* fill in the new call: */ req = priv->current_req; if (req == NULL) { panic ("%s: internal error, requests ran past end of burst\n",prog_name); } call_set_version (call, priv->http_version); method_str = call_method_name[req->method]; call_set_method (call, method_str, strlen (method_str)); call_set_uri (call, req->uri, req->uri_len); #ifdef UW_DYNOUT call->timelimit = req->timelimit; #endif /* UW_DYNOUT */ /* used for call stats */ call->file_size = req->file_size; if (req->cookie_len > 0) { /* add "Cookie:" header if necessary: */ call_append_request_header (call, req->cookie, req->cookie_len); } #ifdef WSESSLOG_HEADERS if (req->contents_len > 0 || req->extra_hdrs_len > 0) { /* add "Content-length:" header and contents, if necessary: */ call_append_request_header (call, req->extra_hdrs, req->extra_hdrs_len); if (req->contents_len > 0) { call_set_contents(call, req->contents, req->contents_len); } } #else if (req->extra_hdrs_len > 0) { /* add "Content-length:" header and contents, if necessary: */ call_append_request_header (call, req->extra_hdrs, req->extra_hdrs_len); call_set_contents (call, req->contents, req->contents_len); } #endif /* WSESSLOG_HEADERS */ #ifdef UW_CALL_STATS if (param.client.id >= 0) { sprintf (call->id_hdr, "Client-Id: %d %d\r\n", param.client.id, (int) call->id); call_append_request_header (call, call->id_hdr, strlen(call->id_hdr)); } #endif /* UW_CALL_STATS */ priv->current_req = req->next; if (DBG > 0) { fprintf (stderr, "%s: accessing URI `%s'\n", prog_name, req->uri); } retval = session_issue_call (sess, call); call_dec_ref (call); if (retval < 0) { return; } } } static void user_think_time_expired (Timer *t, Any_Type arg) { Sess *sess = arg.vp; Sess_Private_Data *priv; assert (object_is_sess (sess)); priv = SESS_PRIVATE_DATA (sess); priv->timer = 0; issue_calls (sess, priv); } /* * Build a CDF for the Request-mix percentage for each video resolution. * The CDF will be used later to generate the requests by the probability. */ static void build_request_mix_cdf(void) { int i = 0; request_mix_cdf = malloc(param.videosesslog.num_logs * sizeof(double)); request_mix_cdf[0] = param.videosesslog.sess_perc[0]; for (i = 1; i < param.videosesslog.num_logs; i++) { request_mix_cdf[i] = request_mix_cdf[i-1] + param.videosesslog.sess_perc[i]; } } /* Create a new session and fill in our private information. */ static int sess_create (Any_Type arg) { Session_Log_Desc *sess_log_desc = NULL; Sess_Private_Data *priv, *template; Sess *sess; double random_val = 0.0; int i = 0; int session_log_index = -1; if (num_sessions_generated++ >= param.num_sessions) { //core_exit(); return -1; } sess = sess_new (); // Choose a log depending on the probability random_val = (double) rand() / (double) RAND_MAX; for (i=0; i< param.videosesslog.num_logs; i++) { if (random_val <= request_mix_cdf[i]) { sess_log_desc = (session_logs+i); session_log_index = i; break; } } //fprintf(stderr, "random_val = %lf, i = %d\n", random_val, i); // Figure out the index in the templates array we are in if (++(sess_log_desc->next_session_template) >= sess_log_desc->num_templates) { sess_log_desc->next_session_template = 0; } template = &sess_log_desc->session_templates[sess_log_desc->next_session_template]; sess->num_requests = template->total_num_reqs; priv = SESS_PRIVATE_DATA (sess); priv->current_burst = template->current_burst; priv->current_req = priv->current_burst->req_list; priv->total_num_reqs = template->total_num_reqs; priv->num_calls_target = priv->current_burst->num_reqs; priv->http_version = template->http_version; sess->port = template->port; sess->server = template->server; strcpy(priv->local_ip, template->local_ip); strcpy(sess->local_ip, template->local_ip); sess->log_index = session_log_index; #ifdef HAVE_SSL sess->use_ssl = template->use_ssl; #endif /* HAVE_SSL */ if (DBG > 0) fprintf (stderr, "Starting session, first burst_len = %d\n", priv->num_calls_target); issue_calls (sess, SESS_PRIVATE_DATA (sess)); return 0; } #ifdef UW_PACE_REQUESTS static void prepare_for_next_burst (Sess *sess, Sess_Private_Data *priv, Time conn_time) #else static void prepare_for_next_burst (Sess *sess, Sess_Private_Data *priv ) #endif /* UW_PACE_REQUESTS */ { Time think_time; Any_Type arg; if (priv->current_burst != NULL) { #ifdef UW_PACE_REQUESTS /* printf( "UW_PACE_REQUESTS: conn_time = %.2f, think_time = %.2f\n", conn_time, priv->current_burst->user_think_time ); */ if (priv->current_burst->pace_requests && priv->current_burst->user_think_time > conn_time) { think_time = priv->current_burst->user_think_time - conn_time; /* printf( "UW_PACE_REQUESTS: wait_time = %.2f\n", think_time ); */ } else #endif /* UW_PACE_REQUESTS */ think_time = priv->current_burst->user_think_time; /* advance to next burst: */ priv->current_burst = priv->current_burst->next; if (priv->current_burst != NULL) { priv->current_req = priv->current_burst->req_list; priv->num_calls_in_this_burst = 0; priv->num_calls_target += priv->current_burst->num_reqs; assert (!priv->timer); arg.vp = sess; priv->timer = timer_schedule (user_think_time_expired, arg, think_time); } } } static void call_destroyed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { Sess_Private_Data *priv; Sess *sess; Call *call; assert (et == EV_CALL_DESTROYED && object_is_call (obj)); call = (Call *) obj; sess = session_get_sess_from_call (call); priv = SESS_PRIVATE_DATA (sess); if (sess->failed) return; ++priv->num_calls_destroyed; if (priv->num_calls_destroyed >= priv->total_num_reqs) { /* we're done with this session */ sess_dec_ref (sess); } else if (priv->num_calls_in_this_burst < priv->current_burst->num_reqs) { issue_calls (sess, priv); } else if (priv->num_calls_destroyed >= priv->num_calls_target) { #ifdef UW_PACE_REQUESTS #ifdef UW_CALL_STATS prepare_for_next_burst (sess, priv, get_call_total_conn_time( call ) ); #else prepare_for_next_burst (sess, priv, 0.0 ); #endif /* UW_CALL_STATS */ #else prepare_for_next_burst (sess, priv ); #endif /* UW_PACE_REQUESTS */ } } /* Allocates memory for a REQ and assigns values to data members. This is used during configuration file parsing only. */ static REQ* new_request (char *uristr) { REQ *retptr; retptr = (REQ *) malloc (sizeof (*retptr)); if (retptr == NULL || uristr == NULL) panic ("%s: ran out of memory while parsing %s\n", prog_name, param.videosesslog.file); memset (retptr, 0, sizeof (*retptr)); retptr->uri = uristr; retptr->uri_len = strlen (uristr); retptr->method = HM_GET; retptr->file_size = -2; #ifdef UW_DYNOUT retptr->timelimit = param.timeout; #endif /* UW_DYNOUT */ return retptr; } /* Like new_request except this is for burst descriptors. */ static BURST* new_burst (REQ *r) { BURST *retptr; retptr = (BURST *) malloc (sizeof (*retptr)); if (retptr == NULL) panic ("%s: ran out of memory while parsing %s\n", prog_name, param.videosesslog.file); memset (retptr, 0, sizeof (*retptr)); retptr->user_think_time = param.videosesslog.think_time; retptr->req_list = r; return retptr; } /* static void add_hash_entries () { struct sockaddr_in *sin; Sess_Private_Data *sptr; int template_num = 0; int port; const char *server; sptr = &session_templates[0]; for (; template_num < num_templates; template_num++) { //use session specific values if it is set //otherwise, us the default port = sptr->port ? sptr->port : param.port; server = sptr->server ? sptr->server : param.server; //check to make sure this entry does not already exist sin = hash_lookup (server, strlen (server), port); if (!sin) { core_addr_intern (server, strlen (server), port); } //next session template sptr++; } } */ /* Read in session-defining configuration file and create in-memory data structures from which to assign uri_s to calls. */ static void parse_config (void) { FILE *fp; int lineno, i; //int reqnum; Sess_Private_Data *sptr; char line[10000]; /* some uri's get pretty long */ char uri[10000]; /* some uri's get pretty long */ u_int major, minor; int http_version; char method_str[1000]; char this_arg[10000]; #ifdef WSESSLOG_HEADERS char headers_str[16384]; /*for capturing extra headers */ char contents[10000] = {0}; #else char contents[10000]; #endif /* WSESSLOG_HEADERS */ #ifdef HAVE_SSL char use_ssl[100]; #endif char server[10000]; int len; double think_time; int bytes_read; REQ *reqptr; //BURST *bptr; BURST *current_burst = 0; char *from, *to, *parsed_so_far; int ch; int single_quoted, double_quoted, escaped, done; int first_req; #ifdef UW_DYNOUT int timelimit = param.timeout; #endif /* UW_DYNOUT */ int file_size = -2; int port; Session_Log_Desc* current_session_log = NULL; int log_file_counter = 0; // Initialize the session_templates, depending on the number of log files specified session_logs = calloc(param.videosesslog.num_logs * sizeof(Session_Log_Desc), 1); // Build the request-mix cdf build_request_mix_cdf(); for (log_file_counter = 0; log_file_counter < param.videosesslog.num_logs; log_file_counter++) { current_session_log = (session_logs + log_file_counter); fp = fopen (param.videosesslog.file[log_file_counter], "r"); if (fp == NULL) { panic ("%s: can't open %s\n", prog_name, param.videosesslog.file); } /* printf("Session templates use %d bytes of memory\n", sizeof(session_templates)); */ current_session_log->num_templates = 0; sptr = &(current_session_log->session_templates[0]); /* default values if they are not specified */ sptr->port = 0; sptr->server = NULL; strcpy(sptr->local_ip, param.videosesslog.local_ip[log_file_counter]); #ifdef HAVE_SSL sptr->use_ssl = 0; #endif for (lineno = 1; fgets (line, sizeof (line), fp); lineno++) { if (line[0] == '#') { continue; /* skip over comment lines */ } if (sscanf (line,"%s%n", uri, &bytes_read) != 1) { /* must be a session-delimiting blank line */ if (sptr->current_req != NULL) { sptr++; /* advance to next session */ /* default values if they are not specified */ sptr->port = 0; sptr->server = NULL; strcpy(sptr->local_ip, param.videosesslog.local_ip[log_file_counter]); #ifdef HAVE_SSL sptr->use_ssl = 0; #endif } continue; } /* session properties*/ if (strncmp (uri, "session", 7) == 0) { parsed_so_far = line + bytes_read; while (sscanf (parsed_so_far, " %s%n", this_arg, &bytes_read) == 1) { if (sscanf (this_arg, "port=%d", &port) == 1) { sptr->port = port; //add_port (port); } else if (sscanf (this_arg, "server=%s", server) == 1) { sptr->server = strdup (server); if (sptr->server == NULL) { panic ("%s: ran out of memory while parsing %s\n", prog_name, param.videosesslog.file); } } #ifdef HAVE_SSL else if (sscanf (this_arg, "ssl=%s", use_ssl) == 1) { if (strncmp (use_ssl, "on", 3) == 0) { sptr->use_ssl = 1; } else if (strncmp (use_ssl, "off", 4) == 0) { sptr->use_ssl = 2; } else { panic ("ssl can be 'on' or 'off', '%s' is not valid\n", use_ssl); } } #endif /* HAVE_SSL */ parsed_so_far += bytes_read; } continue; } /* looks like a request-specifying line */ reqptr = new_request (strdup (uri)); if (sptr->current_req == NULL) { first_req = TRUE; current_session_log->num_templates++; if (current_session_log->num_templates > MAX_SESSION_TEMPLATES) { panic ("%s: too many sessions (%d) specified in %s\n",prog_name, current_session_log->num_templates, param.videosesslog.file); } sptr->http_version = param.http_version; current_burst = sptr->current_burst = new_burst (reqptr); } else { first_req = FALSE; if (!isspace (line[0])) { /* this uri starts a new burst */ current_burst = (current_burst->next = new_burst (reqptr)); } else { sptr->current_req->next = reqptr; } } /* do some common steps for all new requests */ current_burst->num_reqs++; sptr->total_num_reqs++; sptr->current_req = reqptr; /* parse rest of line to specify additional parameters of this request and burst */ parsed_so_far = line + bytes_read; while (sscanf (parsed_so_far, " %s%n", this_arg, &bytes_read) == 1) { if (sscanf (this_arg, "method=%s", method_str) == 1) { for (i = 0; i < HM_LEN; i++) { if (!strncmp (method_str,call_method_name[i],strlen (call_method_name[i]))) { sptr->current_req->method = i; break; } } if (i == HM_LEN) { panic ("%s: did not recognize method '%s' in %s\n",prog_name, method_str, param.videosesslog.file); } } else if (sscanf (this_arg, "think=%lf", &think_time) == 1) { current_burst->user_think_time = think_time; #ifdef UW_PACE_REQUESTS current_burst->pace_requests = 0; #endif /* UW_PACE_REQUESTS */ } #ifdef UW_PACE_REQUESTS else if (sscanf (this_arg, "pace_time=%lf", &think_time) == 1) { current_burst->user_think_time = think_time; current_burst->pace_requests = 1; } #endif /* UW_PACE_REQUESTS */ #ifdef UW_DYNOUT else if (sscanf (this_arg, "timeout=%d", &timelimit) == 1) { sptr->current_req->timelimit = timelimit; } #endif /* UW_DYNOUT */ else if (sscanf (this_arg, "size=%d", &file_size) == 1) { sptr->current_req->file_size = file_size; } #ifdef WSESSLOG_HEADERS else if (sscanf (this_arg, "headers=%s", headers_str) == 1) { /* this is tricky since headers might be a quoted string with embedded spaces or escaped quotes. We should parse this carefully from parsed_so_far */ from = strchr (parsed_so_far, '=') + 1; to = headers_str; single_quoted = FALSE; double_quoted = FALSE; escaped = FALSE; done = FALSE; while ((ch = *from++) != '\0' && !done) { if (escaped == TRUE) { switch (ch) { case 'n': *to++ = '\n'; break; case 'r': *to++ = '\r'; break; case 't': *to++ = '\t'; break; case '\n': *to++ = '\n'; /* this allows an escaped newline to continue the parsing to the next line. */ if (fgets(line,sizeof(line),fp) == NULL) { lineno++; panic ("%s: premature EOF seen in '%s'\n", prog_name, param.videosesslog.file); } parsed_so_far = from = line; break; default: *to++ = ch; break; } escaped = FALSE; } else if (ch == '"' && double_quoted) { double_quoted = FALSE; } else if (ch == '\'' && single_quoted) { single_quoted = FALSE; } else { switch (ch) { case '\t': case '\n': case ' ': if (single_quoted == FALSE && double_quoted == FALSE) done = TRUE; /* we are done */ else *to++ = ch; break; case '\\': /* backslash */ escaped = TRUE; break; case '"': /* double quote */ if (single_quoted) *to++ = ch; else double_quoted = TRUE; break; case '\'': /* single quote */ if (double_quoted) *to++ = ch; else single_quoted = TRUE; break; default: *to++ = ch; break; } } } *to = '\0'; from--; /* back up 'from' to '\0' or white-space */ bytes_read = from - parsed_so_far; int headerslen = strlen(headers_str); if(headerslen != 0 && sptr->current_req->contents_len <= 0) { snprintf (sptr->current_req->extra_hdrs, sizeof(sptr->current_req->extra_hdrs), "%s\r\n", headers_str); sptr->current_req->extra_hdrs_len = strlen (sptr->current_req->extra_hdrs); } else if (headerslen != 0 && sptr->current_req->contents_len > 0) { /* append content length to the end of existing headers */ snprintf (sptr->current_req->extra_hdrs, sizeof(sptr->current_req->extra_hdrs), "%s\r\nContent-length: %d\r\n", headers_str, sptr->current_req->contents_len); sptr->current_req->extra_hdrs_len = strlen (sptr->current_req->extra_hdrs); } } #endif /* WSESSLOG_HEADERS */ else if (strncmp (this_arg, "cookie=", 7) == 0 ||strncmp (this_arg, "contents=", 9) == 0) { /* * These parameters are tricky, since they can involve a * quoted string with whitespace and escaped characters. * Therefore, we can't rely on sscanf(), and must carefully * parse the line ourselves starting at parsed_so_far. * We've bundled 'cookie=' and 'contents=' together simply * to avoid code duplication. */ from = strchr (parsed_so_far, '=') + 1; to = contents; single_quoted = FALSE; double_quoted = FALSE; escaped = FALSE; done = FALSE; while ((ch = *from++) != '\0' && !done) { if (escaped == TRUE) { switch (ch) { case 'n': *to++ = '\n'; break; case 'r': *to++ = '\r'; break; case 't': *to++ = '\t'; break; case '\n': *to++ = '\n'; /* this allows an escaped newline to continue the parsing to the next line. */ if (fgets(line,sizeof(line),fp) == NULL) { lineno++; panic ("%s: premature EOF seen in '%s'\n", prog_name, param.videosesslog.file); } parsed_so_far = from = line; break; default: *to++ = ch; break; } escaped = FALSE; } else if (ch == '"' && double_quoted) { double_quoted = FALSE; } else if (ch == '\'' && single_quoted) { single_quoted = FALSE; } else { switch (ch) { case '\t': case '\n': case ' ': if (single_quoted == FALSE && double_quoted == FALSE) { done = TRUE; /* we are done */ } else { *to++ = ch; } break; case '\\': /* backslash */ escaped = TRUE; break; case '"': /* double quote */ if (single_quoted) { *to++ = ch; } else { double_quoted = TRUE; } break; case '\'': /* single quote */ if (double_quoted) { *to++ = ch; } else { single_quoted = TRUE; } break; default: *to++ = ch; break; } } } from--; /* back up 'from' to '\0' or white-space */ bytes_read = from - parsed_so_far; if ((len = to - contents) > 0) { *to = '\0'; if (strncmp (this_arg, "cookie=", 7) == 0) { /* * The reason for the len + 10 below is to allow for * 'Cookie: ' preceding the cookie data and '\r\n' * following it. */ sptr->current_req->cookie_len = len + 10; sptr->current_req->cookie = malloc(len + 11); sprintf(sptr->current_req->cookie,"Cookie: %s\r\n",contents); } else /* strncmp (this_arg, "contents=", 9) == 0 */ { sptr->current_req->contents_len = len; sptr->current_req->contents = strdup (contents); #ifdef WSESSLOG_HEADERS sprintf(sptr->current_req->extra_hdrs, "%sContent-length: %d\r\n", strdup(sptr->current_req->extra_hdrs), sptr->current_req->contents_len); #else sprintf (sptr->current_req->extra_hdrs,"Content-length: %d\r\n",sptr->current_req->contents_len); #endif /* WSESSLOG_HEADERS */ sptr->current_req->extra_hdrs_len = strlen (sptr->current_req->extra_hdrs); } } } else if (sscanf (this_arg, "http=%u.%u", &major, &minor) == 2) { http_version = (major << 16) | (minor & 0xffff); switch (http_version) { case 0x10000: case 0x10001: break; default: panic ("%s: unsupported HTTP version 0x%x in %s\n",prog_name, http_version, param.videosesslog.file); } if (first_req) { sptr->http_version = http_version; } else if (http_version != sptr->http_version) { panic ("%s: illegal change of HTTP version in %s\n",prog_name, param.videosesslog.file); } } else { /* do not recognize this arg */ panic ("%s: did not recognize arg '%s' in %s\n",prog_name, this_arg, param.videosesslog.file); } parsed_so_far += bytes_read; } } fclose (fp); } /* add any server:port combinations to the core hash table that where specified to be used * by an individual session in the log file */ //add_hash_entries(); /* if (param.session_offsets) { int each; each = num_templates / param.client.num_clients; next_session_template = param.client.id * each; printf("client %d/%d starting at session number %d of %d\n", param.client.id, param.client.num_clients, next_session_template, num_templates); } */ /* if (DBG > 3) { fprintf (stderr,"%s: session list follows:\n\n", prog_name); for (i = 0; i < num_templates; i++) { sptr = &session_templates[i]; fprintf (stderr, "#session %d (total_reqs=%d):\n", i, sptr->total_num_reqs); for (bptr = sptr->current_burst; bptr; bptr = bptr->next) { for (reqptr = bptr->req_list, reqnum = 0;reqptr;reqptr = reqptr->next, reqnum++) { if (reqnum >= bptr->num_reqs) { panic ("%s: internal error detected in parsing %s\n",prog_name, param.videosesslog.file); } if (reqnum > 0) { fprintf (stderr, "\t"); } fprintf (stderr, "%s", reqptr->uri); if (reqnum == 0 && bptr->user_think_time != param.videosesslog.think_time) { #ifdef UW_PACE_REQUESTS if (bptr->pace_requests) fprintf (stderr, " pace=%0.2f",(double) bptr->user_think_time); else #endif fprintf (stderr, " think=%0.2f",(double) bptr->user_think_time); } if (reqptr->method != HM_GET) { fprintf (stderr," method=%s",call_method_name[reqptr->method]); } if (reqptr->contents != NULL) { fprintf (stderr, " contents='%s'", reqptr->contents); } fprintf (stderr, "\n"); } } fprintf (stderr, "\n"); } } */ } static void init (void) { Any_Type arg; parse_config (); sess_private_data_offset = object_expand (OBJ_SESS, sizeof (Sess_Private_Data)); rg_sess.rate = ¶m.rate; rg_sess.tick = sess_create; rg_sess.arg.l = 0; arg.l = 0; event_register_handler (EV_SESS_DESTROYED, sess_destroyed, arg); event_register_handler (EV_CALL_DESTROYED, call_destroyed, arg); /* This must come last so the session event handlers are executed before this module's handlers. */ session_init (); } static void start (void) { rate_generator_start (&rg_sess, EV_SESS_DESTROYED); } Load_Generator videosesslog = { "creates log-based session workload", init, start, no_op }; Sess_Private_Data * priv_from_conn (Conn *conn) { assert (object_is_conn (conn)); Sess * s; Sess_Private_Data *priv; s = session_get_sess_from_conn(conn); priv = SESS_PRIVATE_DATA (s); return priv; } void set_missed_calls(Conn *conn) { assert (conn != NULL); Sess_Private_Data *priv; priv = priv_from_conn (conn); priv->cur_missed_req = priv->current_req; priv->cur_missed_bur = priv->current_burst; priv->prv_missed_req = priv->current_req; } char * get_next_missed_uri(Conn *conn) { assert (conn != NULL); Sess_Private_Data *priv; char * result; result = "--"; if (!conn) { fprintf(stderr, "get_next_missed_uri: Conn became NULL!\n"); } priv = priv_from_conn(conn); assert (priv->cur_missed_bur != NULL); if (priv->cur_missed_req != NULL) { result = priv->cur_missed_req->uri; priv->prv_missed_req = priv->cur_missed_req; priv->cur_missed_req = priv->cur_missed_req->next; } else { priv->cur_missed_bur = priv->cur_missed_bur->next; if (priv->cur_missed_bur != NULL) { priv->cur_missed_req = priv->cur_missed_bur->req_list; result = priv->cur_missed_req->uri; priv->prv_missed_req = priv->cur_missed_req; priv->cur_missed_req = priv->cur_missed_req->next; } } return result; } int get_next_missed_size(Conn *conn) { Sess_Private_Data *priv; priv = priv_from_conn(conn); assert (priv->prv_missed_req != NULL); return priv->prv_missed_req->file_size; } #ifdef UW_DYNOUT int get_next_missed_timelimit(Conn *conn) { Sess_Private_Data *priv; priv = priv_from_conn(conn); assert (priv->prv_missed_req != NULL); return priv->prv_missed_req->timelimit; } #endif /* UW_DYNOUT */ void print_remaining_uri (Conn *conn) { Sess_Private_Data *priv; REQ *cur_req; BURST *cur_bur; priv = priv_from_conn(conn); cur_req = priv->cur_missed_req; cur_bur = priv->cur_missed_bur; while (cur_bur != NULL) { while (cur_req != NULL) { printf("URI: %s\n", cur_req->uri); cur_req = cur_req->next; } cur_bur = cur_bur->next; if (cur_bur != NULL) { cur_req = cur_bur->req_list; } } } int num_missed_calls (Conn *conn) { Sess_Private_Data *priv; priv = priv_from_conn(conn); if (conn->state >= S_CONNECTED) { return priv->total_num_reqs - priv->num_calls_destroyed - 1; } else { return priv->total_num_reqs; } } ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/gen/videosesslog.h ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _WSESSLOG_H_ #define _WSESSLOG_H_ #ifdef UW_CALL_STATS #include #include /* This function is for testing purposes * It will print out the remaining uris to be requested fora given connection */ void print_remaining_uri (Conn * conn); /* This function returns the number of calls that are remaining * NOTE: this is intented to be used by call_stats after a connection times out */ int num_missed_calls(Conn * conn); /* This function sets the private data structs up befor get_next_missed_uri is called * NOTE: this is intented to be used by call_stats after a connection times out */ void set_missed_calls(Conn *conn); /* This function returns the uri of the next request in order * NOTE: this is intented to be used by call_stats after a connection times out */ char * get_next_missed_uri(Conn *conn); /* This function returns the file size of the next request in order * NOTE: this is intented to be used by call_stats after a connection times out */ int get_next_missed_size(Conn *conn); #ifdef UW_DYNOUT /* This function returns the timelimit of the next request in order * NOTE: this is intented to be used by call_stats after a connection times out */ int get_next_missed_timelimit(Conn *conn); #endif /* UW_DYNOUT */ #endif /* UW_CALL_STATS */ #endif /* _WSESSLOG_H_ */ ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/gen/wsess.c ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Creates sessions at the fixed rate PARAM.RATE. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define SESS_PRIVATE_DATA(c) \ ((Sess_Private_Data *) ((char *)(c) + sess_private_data_offset)) typedef struct Sess_Private_Data { u_int num_calls_in_this_burst; /* # of calls created for this burst */ u_int num_calls_target; /* total # of calls desired */ u_int num_calls_destroyed; /* # of calls destroyed so far */ Timer *timer; /* timer for session think time */ } Sess_Private_Data; static size_t sess_private_data_offset; static int num_sessions_generated; static int num_sessions_destroyed; static Rate_Generator rg_sess; static void issue_calls (Sess *sess, Sess_Private_Data *priv) { int i, to_create, retval; Call *call; /* Mimic browser behavior of fetching html object, then a couple of embedded objects: */ to_create = 1; if (priv->num_calls_in_this_burst > 0) to_create = param.burst_len - priv->num_calls_in_this_burst; priv->num_calls_in_this_burst += to_create; for (i = 0; i < to_create; ++i) { call = call_new (); if (!call) { sess_failure (sess); return; } retval = session_issue_call (sess, call); call_dec_ref (call); if (retval < 0) return; } } static void user_think_time_expired (Timer *t, Any_Type arg) { Sess *sess = arg.vp; Sess_Private_Data *priv; assert (object_is_sess (sess)); priv = SESS_PRIVATE_DATA (sess); priv->timer = 0; issue_calls (sess, priv); } static void call_destroyed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { Any_Type arg; Sess *sess; Call *call; Sess_Private_Data *priv; assert (et == EV_CALL_DESTROYED && object_is_call (obj)); call = (Call *) obj; sess = session_get_sess_from_call (call); priv = SESS_PRIVATE_DATA (sess); ++priv->num_calls_destroyed; if (priv->num_calls_destroyed >= param.wsess.num_calls) { /* we're done with this session */ if (!sess->failed) sess_dec_ref (sess); } else if (priv->num_calls_in_this_burst < param.burst_len) /* now that we received the reply to the first call in this burst, create the remaining calls */ issue_calls (sess, priv); else if (priv->num_calls_destroyed >= priv->num_calls_target) { /* we're done with this burst---schedule the user-think-time timer */ priv->num_calls_in_this_burst = 0; priv->num_calls_target += param.burst_len; assert (!priv->timer); arg.vp = sess; priv->timer = timer_schedule (user_think_time_expired, arg, param.wsess.think_time); } } /* Create a new session. */ static int sess_create (Any_Type arg) { Sess_Private_Data *priv; Sess *sess; if (num_sessions_generated++ >= param.wsess.num_sessions) return -1; sess = sess_new (); if (!sess) return 1; priv = SESS_PRIVATE_DATA (sess); priv->num_calls_target = param.burst_len; issue_calls (sess, SESS_PRIVATE_DATA (sess)); return 0; } static void sess_destroyed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { Sess_Private_Data *priv; Sess *sess; assert (et == EV_SESS_DESTROYED && object_is_sess (obj)); sess = (Sess *) obj; priv = SESS_PRIVATE_DATA (sess); if (priv->timer) { timer_cancel (priv->timer); priv->timer = 0; } if (++num_sessions_destroyed >= param.wsess.num_sessions) core_exit (); } static void init (void) { Any_Type arg; #ifdef UW_CALL_STATS if (param.call_stats >= 0) { fprintf(stderr, "Can not use --call-stats with --wsess\n"); exit(1); } #endif /* UW_CALL_STATS */ session_init (); sess_private_data_offset = object_expand (OBJ_SESS, sizeof (Sess_Private_Data)); rg_sess.rate = ¶m.rate; rg_sess.tick = sess_create; rg_sess.arg.l = 0; arg.l = 0; event_register_handler (EV_SESS_DESTROYED, sess_destroyed, arg); event_register_handler (EV_CALL_DESTROYED, call_destroyed, arg); } static void start (void) { rate_generator_start (&rg_sess, EV_SESS_DESTROYED); } Load_Generator wsess = { "creates session workload", init, start, no_op }; ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/gen/wsesspage.c ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Similar to wsess but instead of generating fixed bursts, each fetched html page is parsed and the embedded objects are fetched in a burst. This is NOT a high performance workload generator! Use it only for non-performance critical tests. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define CALL_PRIVATE_DATA(c) \ ((Call_Private_Data *) ((char *)(c) + call_private_data_offset)) #define SESS_PRIVATE_DATA(c) \ ((Sess_Private_Data *) ((char *)(c) + sess_private_data_offset)) typedef struct Call_Private_Data { enum { P_INITIAL, P_HTML, P_CMD, /* we saw a `<' and are scanning for the end of CMD */ P_DASH_ONE, /* looking for the first dash of a comment close */ P_DASH_TWO, /* looking for the second dash of a comment close */ P_RANGLE, /* looking for '>' */ P_SRC, /* we're looking for "src" */ P_DATA, /* we're looking for "data" */ P_LQUOTE, /* we're looking for the left quote of a URI */ P_NAKED_URI, /* we're looking for an unquoted URI */ P_QUOTED_URI /* we're looking for a quoted URI */ } state; int buf_len; char buf[1024]; void *to_free; /* call queue element to free when done */ } Call_Private_Data; typedef struct Sess_Private_Data { u_int num_created; /* # of calls created in this burst */ u_int num_destroyed; /* # of calls destroyed in this burst */ u_int num_reqs_completed; /* # of user reqs completed */ Timer *timer; /* timer for session think time */ struct uri_list { struct uri_list *next; size_t uri_len; char uri[1]; /* really URI_LEN+1 bytes... */ } *uri_list; } Sess_Private_Data; static size_t sess_private_data_offset; static size_t call_private_data_offset; static int num_sessions_generated; static int num_sessions_destroyed; static Rate_Generator rg_sess; static size_t prefix_len; static char *prefix; static void issue_calls (Sess *sess, Sess_Private_Data *priv) { int i, to_create, retval, embedded = 0; Call_Private_Data *cpriv; struct uri_list *el; Call *call; /* Mimic browser behavior of fetching html object, then a couple of embedded objects: */ to_create = 1; if (priv->num_created > 0) { to_create = session_max_qlen (sess) - session_current_qlen (sess); embedded = 1; } for (i = 0; i < to_create && (!embedded || priv->uri_list); ++i) { ++priv->num_created; call = call_new (); if (!call) { sess_failure (sess); return; } if (embedded) { el = priv->uri_list; priv->uri_list = el->next; cpriv = CALL_PRIVATE_DATA (call); cpriv->to_free = el; call_set_uri (call, el->uri, el->uri_len); } if (verbose > 1) printf ("%s: fetching `%s'\n", prog_name, (char *)call->req.iov[IE_URI].iov_base); retval = session_issue_call (sess, call); call_dec_ref (call); if (retval < 0) return; } } static void fetch_uri (Sess *sess, Sess_Private_Data *priv, Call_Private_Data *cpriv, const char *uri, size_t uri_len) { struct uri_list *el; int is_relative; size_t len; char *dst; if (strchr (uri, ':')) { len = strlen (param.server); if (strncmp (uri, "http://", 7) == 0 && strncmp (uri + 7, param.server, len) == 0 && uri[7 + len] == '/') { uri += 7 + len; uri_len -= 7 + len; } else { /* Eventually, we may want to create new sessions on the fly, but for now, we simply punt on non-absolute URIs */ if (verbose > 1) fprintf (stderr, "%s: ignoring absolute URI `%s'\n", prog_name, uri); return; } } is_relative = (uri[0] != '/'); /* enqueue the new uri: */ len = uri_len; if (is_relative) len += prefix_len; el = malloc (sizeof (*el) + len); if (!el) panic ("%s.fetch_uri: out of memory!\n", prog_name); el->uri_len = len; dst = el->uri; if (is_relative) { memcpy (el->uri, prefix, prefix_len); dst += prefix_len; } memcpy (dst, uri, uri_len + 1); el->next = priv->uri_list; priv->uri_list = el; issue_calls (sess, priv); } static void user_think_time_expired (Timer *t, Any_Type arg) { Sess *sess = arg.vp; Sess_Private_Data *priv; assert (object_is_sess (sess)); priv = SESS_PRIVATE_DATA (sess); priv->timer = 0; issue_calls (sess, priv); } static void call_recv_hdr (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { Call_Private_Data *cpriv; Sess_Private_Data *priv; struct iovec *line; Call *call; Sess *sess; char *hdr; assert (et == EV_CALL_RECV_HDR && object_is_call (obj)); call = (Call *) obj; cpriv = CALL_PRIVATE_DATA (call); sess = session_get_sess_from_call (call); priv = SESS_PRIVATE_DATA (sess); line = callarg.vp; hdr = line->iov_base; switch (tolower (hdr[0])) { case 'c': if (line->iov_len >= 23 && strncasecmp (hdr + 1, "ontent-type: text/html", 22) == 0) cpriv->state = P_HTML; break; case 'l': if (line->iov_len > 10 && strncasecmp (hdr + 1, "ocation: ", 9) == 0) fetch_uri (sess, priv, cpriv, hdr + 10, line->iov_len - 10); break; } } static void call_recv_data (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { Call_Private_Data *cpriv; Sess_Private_Data *priv; const char *cp, *end; struct iovec *line; Sess *sess; Call *call; int ch; assert (et == EV_CALL_RECV_DATA && object_is_call (obj)); call = (Call *) obj; cpriv = CALL_PRIVATE_DATA (call); sess = session_get_sess_from_call (call); priv = SESS_PRIVATE_DATA (sess); if (cpriv->state == P_INITIAL) return; /* not an html object */ line = callarg.vp; cp = line->iov_base; end = cp + line->iov_len; while (cp < end) { ch = *cp++; switch (cpriv->state) { case P_INITIAL: break; case P_HTML: cpriv->buf_len = 0; if (ch == '<') cpriv->state = P_CMD; break; case P_CMD: if (isspace (ch) || ch == '=') { if (cpriv->buf_len > 0) { if (DBG > 3) fprintf (stderr, "found command `%.*s'\n", cpriv->buf_len, cpriv->buf); if (cpriv->buf_len == 3 && strcmp (cpriv->buf, "!--") == 0) cpriv->state = P_DASH_ONE; else if (cpriv->buf_len == 5 && strncasecmp (cpriv->buf, "frame", 5) == 0) cpriv->state = P_SRC; else if (cpriv->buf_len == 6 && strncasecmp (cpriv->buf, "iframe", 6) == 0) cpriv->state = P_SRC; else if (cpriv->buf_len == 6 && strncasecmp (cpriv->buf, "data", 6) == 0) cpriv->state = P_DATA; else if (cpriv->buf_len == 3 && strncasecmp (cpriv->buf, "img", 3) == 0) cpriv->state = P_SRC; cpriv->buf_len = 0; } else cpriv->state = P_HTML; } else if (ch == '>') cpriv->state = P_HTML; else if (cpriv->buf_len < sizeof (cpriv->buf)) cpriv->buf[cpriv->buf_len++] = ch; break; case P_DASH_ONE: if (ch == '-') cpriv->state = P_DASH_TWO; break; case P_DASH_TWO: cpriv->state = (ch == '-') ? P_RANGLE : P_DASH_ONE; break; case P_RANGLE: if (ch == '>') cpriv->state = P_HTML; break; case P_SRC: if (ch == '>') cpriv->state = P_HTML; else { cpriv->buf[cpriv->buf_len++] = ch; if (cpriv->buf_len == 4) { if (strncasecmp (cpriv->buf, "src=", 4) == 0) { cpriv->state = P_LQUOTE; cpriv->buf_len = 0; } else { memcpy (cpriv->buf, cpriv->buf + 1, 3); cpriv->buf_len = 3; } } } break; case P_DATA: if (ch == '>') cpriv->state = P_HTML; else { cpriv->buf[cpriv->buf_len++] = ch; if (cpriv->buf_len == 5) { if (strncasecmp (cpriv->buf, "data=", 5) == 0) { cpriv->state = P_LQUOTE; cpriv->buf_len = 0; } else { memcpy (cpriv->buf, cpriv->buf + 1, 4); cpriv->buf_len = 4; } } } break; case P_LQUOTE: if (ch == '"') cpriv->state = P_QUOTED_URI; else if (!isspace (ch)) { cpriv->state = P_NAKED_URI; cpriv->buf[cpriv->buf_len++] = ch; } break; case P_NAKED_URI: case P_QUOTED_URI: if ((cpriv->state == P_QUOTED_URI && ch == '"') || (cpriv->state == P_NAKED_URI && isspace (ch))) { cpriv->buf[cpriv->buf_len] = '\0'; fetch_uri (sess, priv, cpriv, cpriv->buf, cpriv->buf_len); cpriv->state = P_HTML; cpriv->buf_len = 0; } else if (cpriv->buf_len < sizeof (cpriv->buf) - 1) cpriv->buf[cpriv->buf_len++] = ch; break; } } } static void call_destroyed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { Call_Private_Data *cpriv; Sess_Private_Data *priv; Any_Type arg; Sess *sess; Call *call; assert (et == EV_CALL_DESTROYED && object_is_call (obj)); call = (Call *) obj; cpriv = CALL_PRIVATE_DATA (call); sess = session_get_sess_from_call (call); priv = SESS_PRIVATE_DATA (sess); if (cpriv->to_free) { free (cpriv->to_free); cpriv->to_free = 0; } ++priv->num_destroyed; if (sess->failed) return; if (priv->uri_list) /* there are some queued URI's which we may be able to issue now */ issue_calls (sess, priv); else if (priv->num_destroyed >= priv->num_created) { /* we're done with this burst */ if (++priv->num_reqs_completed >= param.wsesspage.num_reqs) /* we're done with this session */ sess_dec_ref (sess); else { /* schedule the user-think-time timer */ priv->num_created = 0; assert (!priv->timer); arg.vp = sess; priv->timer = timer_schedule (user_think_time_expired, arg, param.wsesspage.think_time); } } } /* Create a new session. */ static int sess_create (Any_Type arg) { Sess *sess; if (num_sessions_generated++ >= param.wsesspage.num_sessions) return -1; sess = sess_new (); if (!sess) return 1; issue_calls (sess, SESS_PRIVATE_DATA (sess)); return 0; } static void sess_destroyed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { Sess_Private_Data *priv; Sess *sess; assert (et == EV_SESS_DESTROYED && object_is_sess (obj)); sess = (Sess *) obj; priv = SESS_PRIVATE_DATA (sess); if (priv->timer) { timer_cancel (priv->timer); priv->timer = 0; } if (++num_sessions_destroyed >= param.wsesspage.num_sessions) core_exit (); } static void init (void) { const char *slash; Any_Type arg; #ifdef UW_CALL_STATS if (param.call_stats >= 0) { fprintf(stderr, "Can not use --call-stats with --wsesspage\n"); exit(1); } #endif /* UW_CALL_STATS */ slash = strrchr (param.uri, '/'); if (slash) prefix_len = (slash + 1) - param.uri; else panic ("%s: URI specified with --uri must be absolute", prog_name); prefix = strdup (param.uri); prefix[prefix_len] = '\0'; session_init (); call_private_data_offset = object_expand (OBJ_CALL, sizeof (Call_Private_Data)); sess_private_data_offset = object_expand (OBJ_SESS, sizeof (Sess_Private_Data)); rg_sess.rate = ¶m.rate; rg_sess.tick = sess_create; rg_sess.arg.l = 0; arg.l = 0; event_register_handler (EV_CALL_RECV_HDR, call_recv_hdr, arg); event_register_handler (EV_CALL_RECV_DATA, call_recv_data, arg); event_register_handler (EV_SESS_DESTROYED, sess_destroyed, arg); event_register_handler (EV_CALL_DESTROYED, call_destroyed, arg); } static void start (void) { rate_generator_start (&rg_sess, EV_SESS_DESTROYED); } Load_Generator wsesspage = { "creates sessions that fetch html pages and embedded objects", init, start, no_op }; ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/http.c ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* Read a CRLF terminated line of characters into c->reply.line. Returns 1 when the line is complete, 0 when the line is incomplete and more data is needed. */ static int get_line (Call *c, char **bufp, size_t *buf_lenp) { size_t to_copy, buf_len = *buf_lenp; Conn *s = c->conn; char *buf = *bufp; const char *eol; int has_lf; if (buf_len <= 0) return 0; /* Note that core.c guarantees that BUF is '\0' terminated. */ eol = strchr (buf, '\n'); if (eol) ++eol; else eol = buf + buf_len; to_copy = eol - buf; buf_len -= to_copy; if (s->line.iov_len + to_copy >= sizeof (s->line_buf)) { fprintf (stderr, "%s.get_line: truncating header from %lu to %lu bytes\n", prog_name, (u_long) (s->line.iov_len + to_copy), (u_long) sizeof (s->line_buf)); to_copy = sizeof (s->line_buf) - 1 - s->line.iov_len; } memcpy ((char *) s->line.iov_base + s->line.iov_len, buf, to_copy); s->line.iov_len += to_copy; has_lf = ((char *) s->line.iov_base)[s->line.iov_len - 1] == '\n'; *bufp = (char *) eol; *buf_lenp = buf_len; if (has_lf || s->line.iov_len == sizeof (s->line_buf) - 1) { /* We got a full header line. Chop off \r\n at the tail if necessary. */ if (((char *) s->line.iov_base)[s->line.iov_len - 1] == '\n') { --s->line.iov_len; if (((char *) s->line.iov_base)[s->line.iov_len - 1] == '\r') --s->line.iov_len; } ((char *) s->line.iov_base)[s->line.iov_len] = '\0'; return 1; } return 0; } static void parse_status_line (Call *c, char **bufp, size_t *buf_lenp) { char *buf, *buf_start = *bufp; u_int major, minor, status; Conn *s = c->conn; Any_Type arg; s->is_chunked = 0; /* default to "infinite" content length: */ s->content_length = ~(size_t) 0; if (!get_line (c, bufp, buf_lenp)) return; buf = c->conn->line.iov_base; if (sscanf (buf, "HTTP/%u.%u %u ", &major, &minor, &status) == 3) { c->reply.version = 0x10000*major + minor; c->reply.status = status; } else { c->reply.version = 0x10000; /* default to 1.0 */ c->reply.status = 599; if (c->reply.status == 599) { fprintf (stderr, "%s.parse_status_line: invalid status line `%s'!!\n", prog_name, buf); fprintf (stdout, "%s.parse_status_line: invalid status line `%s'!!\n", prog_name, buf); } } if (DBG > 0) fprintf (stderr, "parse_status_line.%lu: reply is HTTP/%u.%u, status = %d\n", c->id, c->reply.version / 0x10000, c->reply.version & 0xffff, c->reply.status); /* Determine whether we should be expecting a message body. HEAD never includes an entity. For other methods, things depend on the status code. */ if (strcmp ((char *) c->req.iov[IE_METHOD].iov_base, "HEAD") == 0) s->has_body = 0; else { s->has_body = 1; switch (status / 100) { case 1: /* informational */ s->has_body = 0; if (status == 100) { arg.l = c->reply.status; event_signal (EV_CALL_RECV_START, (Object *) c, arg); s->state = S_REPLY_CONTINUE; goto done; } break; case 2: /* success */ case 3: /* redirection */ switch (status) { case 204: /* No Content */ case 205: /* Reset Content */ case 304: /* Not Modified */ s->has_body = 0; break; } break; case 4: /* client errors */ case 5: /* server errors */ break; default: fprintf (stderr, "%s.parse_status_line: bad status %u\n", prog_name, status); fprintf (stdout, "%s.parse_status_line: bad status %u\n", prog_name, status); break; } } arg.l = c->reply.status; event_signal (EV_CALL_RECV_START, (Object *) c, arg); if (s->state >= S_CLOSING) return; s->state = S_REPLY_HEADER; done: c->reply.header_bytes += *bufp - buf_start; s->line.iov_len = 0; } static void parse_headers (Call *c, char **bufp, size_t *buf_lenp) { char *hdr, *buf_start = *bufp; Conn *s = c->conn; size_t hdr_len; Any_Type arg; while (get_line (c, bufp, buf_lenp) > 0) { hdr = s->line.iov_base; hdr_len = s->line.iov_len; if (!hdr_len) { /* empty header implies end of headers */ if (s->has_body) if (s->is_chunked) { s->content_length = 0; s->state = S_REPLY_CHUNKED; } else s->state = S_REPLY_DATA; else if (s->state == S_REPLY_CONTINUE) s->state = S_REPLY_HEADER; else s->state = S_REPLY_DONE; break; } /* process line as a regular header: */ switch (tolower (*hdr)) { case 'c': if (strncasecmp (hdr, "content-length:", 15) == 0) { hdr += 15; s->content_length = strtoul (hdr, 0, 10); if (DBG > 0) { fprintf(stderr, "parse_headers: content-length = %zd\n", s->content_length); } } break; case 't': if (strncasecmp (hdr, "transfer-encoding:", 18) == 0) { hdr += 18; while (isspace (*hdr)) ++hdr; if (strcasecmp (hdr, "chunked") == 0) s->is_chunked = 1; else fprintf (stderr, "%s.parse_headers: unknown transfer " "encoding `%s'\n", prog_name, hdr); } break; } arg.vp = &s->line; event_signal (EV_CALL_RECV_HDR, (Object *) c, arg); if (s->state >= S_CLOSING) return; s->line.iov_len = 0; } c->reply.header_bytes += *bufp - buf_start; } static void parse_footers (Call *c, char **bufp, size_t *buf_lenp) { char *buf_start = *bufp; Conn *s = c->conn; size_t hdr_len; Any_Type arg; if (DBG > 0) { fprintf(stderr, "parse_footers: c = %p, bufp = %p buf_len = %d\n", c, *bufp, (int) *buf_lenp); } while (get_line (c, bufp, buf_lenp) > 0) { hdr_len = s->line.iov_len; if (!hdr_len) { /* empty footer implies end of footers */ s->state = S_REPLY_DONE; break; } /* process line as a regular footer: */ arg.vp = &s->line; event_signal (EV_CALL_RECV_FOOTER, (Object *) c, arg); if (s->state >= S_CLOSING) return; s->line.iov_len = 0; } c->reply.footer_bytes += *bufp - buf_start; } static int parse_data (Call *c, char **bufp, size_t *buf_lenp) { size_t bytes_needed, buf_len = *buf_lenp; Conn *s = c->conn; char *buf = *bufp; struct iovec iov; Any_Type arg; bytes_needed = (s->content_length - c->reply.content_bytes); if (buf_len > bytes_needed) buf_len = bytes_needed; if (param.verify_reply) { memcpy(c->reply.content + c->reply.content_bytes, buf, buf_len ); } iov.iov_base = (caddr_t) buf; iov.iov_len = buf_len; arg.vp = &iov; event_signal (EV_CALL_RECV_DATA, (Object *) c, arg); c->reply.content_bytes += buf_len; *bufp = buf + buf_len; *buf_lenp -= buf_len; return (buf_len == bytes_needed); } static void xfer_chunked (Call *c, char **bufp, size_t *buf_lenp) { Conn *s = c->conn; size_t chunk_length; char *end; while (*buf_lenp > 0 && s->state < S_CLOSING) { if (c->reply.content_bytes >= s->content_length) { /* need to parse next chunk length line: */ if (!get_line (c, bufp, buf_lenp)) return; /* need more data */ if (s->line.iov_len == 0) continue; /* skip over empty line */ errno = 0; chunk_length = strtoul (s->line.iov_base, &end, 16); s->line.iov_len = 0; if (errno == ERANGE || end == s->line.iov_base) { fprintf (stderr, "%s.xfer_chunked: bad chunk line `%s'\n", prog_name, (char *) s->line.iov_base); continue; } if (chunk_length == 0) { /* a final chunk of zero bytes indicates the end of the reply */ s->state = S_REPLY_FOOTER; return; } s->content_length += chunk_length; } parse_data (c, bufp, buf_lenp); } } #define PATHLEN 256 void verify_reply_data (Call * c ) { int fd; /* File descriptor */ struct stat fstat_info; /* For fstat information */ int size; /* Size of the file (in bytes) */ char * file_content; /* Read the file off disk into this buf */ int rc; /* Syscall return codes */ char path[PATHLEN]; /* Path to the file */ char * uri; /* Request uri */ int len; /* Used to calculate path lengths */ uri = (char *) c->req.iov[IE_URI].iov_base; assert(uri != NULL); /* Build path to file */ len = strlen(param.verify_dir); strncpy(path, param.verify_dir, len); strncpy(path+len, uri, PATHLEN - len); path[PATHLEN-1] = '\0'; /* Open the reference file */ fd = open(path, O_RDONLY); if ( fd < 0 ) { printf("Unable to open reference file for reading\n"); exit(1); } /* fstat the reference file */ rc = fstat(fd, &fstat_info); if ( rc < 0 ) { printf("Unable to fstat file in reference fileset\n"); exit(1); } size = fstat_info.st_size; /* Compare the file size to the length of the server's reply */ if ( c->reply.content_bytes != size ) { printf("Error:Server reply contains %lld bytes " "but the referenced file contains %lld bytes\n", (long long) c->reply.content_bytes, (long long) fstat_info.st_size); exit(1); } /* Allocate a buffer for reading */ file_content = (char*) malloc( size ); assert( file_content != NULL ); /* Read the file off the disk */ rc = read( fd, file_content, size ); if ( rc < 0 ) { printf("Error: Unable to read reference file\n"); exit(1); } /* Compare the file data to the server's reply data */ if ( strncmp( c->reply.content, file_content, size) != 0 ) { printf("Error: Server reply does not match reference file!\n"); exit(1); } /* Cleanup - should also be done in error cases above */ close(fd); free(file_content); } void http_process_reply_bytes (Call *c, char **bufp, size_t *buf_lenp) { Conn *s = c->conn; struct iovec iov; Any_Type arg; iov.iov_base = *bufp; iov.iov_len = *buf_lenp; arg.vp = &iov; event_signal (EV_CALL_RECV_RAW_DATA, (Object *) c, arg); do { switch (s->state) { case S_REPLY_STATUS: parse_status_line (c, bufp, buf_lenp); break; case S_REPLY_HEADER: parse_headers (c, bufp, buf_lenp); /* Allocate a buffer to hold the reply. Later on we'll verify the bytes */ if ( param.verify_reply && s->content_length > 0 && c->reply.content == NULL ) { c->reply.content = (char*) malloc(s->content_length); assert( c->reply.content != NULL ); } break; case S_REPLY_FOOTER: parse_footers (c, bufp, buf_lenp); break; case S_REPLY_DATA: if (parse_data (c, bufp, buf_lenp) && s->state < S_CLOSING) { if (param.verify_reply ) verify_reply_data(c); s->state = S_REPLY_DONE; } break; case S_REPLY_CONTINUE: parse_headers (c, bufp, buf_lenp); break; case S_REPLY_CHUNKED: xfer_chunked (c, bufp, buf_lenp); break; case S_REPLY_DONE: return; default: fprintf (stderr, "%s.http_process_reply_bytes: bad state %d\n", prog_name, s->state); exit (1); } } while (*buf_lenp > 0 && s->state < S_CLOSING); } ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/http.h ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef http_h #define http_h #include #include #include extern void http_process_reply_bytes (Call *c, char **buf, size_t *buf_len); #endif /* http_h */ ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/httperf.c ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Fundamentals: There are three subsystems to httperf: 1) The load generator which determines what URI is fetched next. 2) The core engine that handles the mechanics of issuing a request. 3) The instrumentation infrastructure that measures various aspects of the transaction(s). Since there is considerable potential variation in all three, it seems like an event-based approach might be ideal in tying the three together. Ideally, it should be possible to write a new load generator without modifications to the other subsystems. Similarly, it should be possible to add instrumentation without requiring changes to the load generator or http engine. Axioms: - The only point at which the client will fall back is if the client itself is overloaded. There is no point trying to fix up this case---simply declare defeat and abort the test. */ #include "config.h" #ifdef __FreeBSD__ #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_SSL # include #endif #define RATE_INTERVAL 5.0 #define STATS_INTERVAL 15.0 #define MAX_HOSTNAME_LEN (100) const char *prog_name; int verbose; Cmdline_Params param; Time test_time_start; Time test_time_stop; struct rusage test_rusage_start; struct rusage test_rusage_stop; size_t object_type_size[OBJ_NUM_TYPES]; Time dump_stats_start; #ifdef HAVE_SSL SSL_CTX *ssl_ctx; #endif #ifdef DEBUG int debug_level; #endif static Time perf_sample_start; static struct option longopts[] = { {"add-header", required_argument, (void *) ¶m.additional_header, 0}, {"burst-length", required_argument, ¶m.burst_len, 0}, {"client", required_argument, (void *) ¶m.client, 0}, {"client-session-offsets", no_argument, (void *) ¶m.session_offsets, 1}, {"close-with-reset", no_argument, ¶m.close_with_reset, 1}, {"timeout-with-reset", no_argument, ¶m.timeout_with_reset, 1}, {"debug", required_argument, 0, 'd'}, #ifdef HAVE_EPOLL {"epoll", no_argument, ¶m.use_epoll, 1}, #endif /* HAVE_EPOLL */ {"failure-status", required_argument, ¶m.failure_status, 0}, {"help", no_argument, 0, 'h'}, {"hog", no_argument, ¶m.hog, 1}, {"http-version", required_argument, (void *) ¶m.http_version, 0}, {"lb-ports", required_argument, (void *) ¶m.lb_ports, 0}, {"max-connections", required_argument, ¶m.max_conns, 0}, #ifdef IDLECONN {"idle-connections", required_argument, ¶m.idle_conns, 0}, {"idleconn", required_argument, (void *) ¶m.idleconn, 0}, #endif /* IDLECONN */ {"max-piped-calls", required_argument, ¶m.max_piped, 0}, {"method", required_argument, (void *) ¶m.method, 0}, {"no-host-hdr", no_argument, ¶m.no_host_hdr, 1}, {"num-calls", required_argument, (void *) ¶m.num_calls, 0}, {"num-conns", required_argument, (void *) ¶m.num_conns, 0}, {"period", required_argument, (void *) ¶m.rate.mean_iat, 0}, {"port", required_argument, (void *) ¶m.port, 0}, {"print-reply", optional_argument, ¶m.print_reply, 0}, {"print-request",optional_argument, ¶m.print_request, 0}, #ifdef UW_STABLE_STATS {"ramp-up-num-conns", required_argument, (void *) ¶m.ramp_up_conns, 0}, {"ramp-down-num-conns", required_argument, (void *) ¶m.ramp_down_conns, 0}, {"stagger-start", no_argument, ¶m.client.stagger_start, 1}, #endif /* UW_STABLE_STATS */ {"rate", required_argument, (void *) ¶m.rate, 0}, {"rate-interval", required_argument, (void *) ¶m.rate_interval, 0}, {"recv-buffer", required_argument, (void *) ¶m.recv_buffer_size, 0}, {"retry-on-failure", no_argument, ¶m.retry_on_failure, 1}, {"send-buffer", required_argument, (void *) ¶m.send_buffer_size, 0}, {"server", required_argument, (void *) ¶m.server, 0}, {"server-name", required_argument, (void *) ¶m.server_name, 0}, {"session-cookies", no_argument, (void *) ¶m.session_cookies, 1}, #ifdef HAVE_SSL {"ssl", no_argument, ¶m.use_ssl, 1}, {"ssl-ciphers", required_argument, (void *) ¶m.ssl_cipher_list, 0}, {"ssl-no-reuse", no_argument, ¶m.ssl_reuse, 0}, #endif {"spec-stats", no_argument, (void *) ¶m.spec_stats, 1}, #ifdef UW_CALL_STATS {"call-stats", required_argument, (void *) ¶m.call_stats, -1}, {"call-stats-file", required_argument, (void *) ¶m.call_stats_file, 0}, #endif {"separate-post-stats", no_argument, (void *) ¶m.separate_post_stats, 1}, {"stats-interval",required_argument, (void *) ¶m.stats_interval, 0}, {"think-timeout",required_argument, (void *) ¶m.think_timeout, 0}, {"timeout", required_argument, (void *) ¶m.timeout, 0}, {"uri", required_argument, (void *) ¶m.uri, 0}, #ifdef HAVE_SCHED_AFFINITY {"use-cpu-mask", required_argument, (void *) ¶m.cpu_mask, 0}, #endif {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, {"videosesslog", required_argument, (void *) ¶m.videosesslog, 0}, {"num-sessions", required_argument, (void *) ¶m.num_sessions, 0}, {"output-log", required_argument, (void *) ¶m.output_log, 0}, {0, 0, 0, 0} }; static void usage (void) { printf ("Usage: %s " "[-hdvV] [--add-header S] [--burst-length N] [--client N/N]\n" "\t[--close-with-reset] [--debug N] [--failure-status N]\n" "\t[--timeout-with-reset]\n" "\t[--help] [--hog] [--http-version S] [lb-ports P1,...,Pn]\n" "\t[--max-connections N]\n" #ifdef HAVE_EPOLL "\t[--epoll]\n" #endif /* HAVE_EPOLL */ #ifdef IDLECONN "\t[--idle-connections N]\n" "\t[--idleconn ]\n" #endif /* IDLECONN */ "\t[--max-piped-calls N] [--method S] [--no-host-hdr]\n" #ifndef SRINI_RATE "\t[--num-calls N] [--num-conns N] [--period [d|u|e|v|l]T1" "[,D1][,T2][,D2]]\n" #else "\t[--num-calls N] [--num-conns N] [--period [d|u|e]T1[,T2]]\n" #endif "\t[--port N] " "[--print-reply [header|body]] [--print-request [header|body]]\n" "\t[--rate X] [--rate-interval X] [--recv-buffer N] [--retry-on-failure] " "[--send-buffer N]\n" #ifdef UW_STABLE_STATS "\t[--ramp-up-num-conns N] [--ramp-down-num-conns N]\n" "\t[--stagger-start]\n" #endif /* UW_STABLE_STATS */ "\t[--server S] [--server-name S] [--session-cookies] \n" "\t[--spec-stats]\n" #ifdef UW_CALL_STATS "\t[--call-stats N]\n" "\t[--call-stats-file S]\n" #endif "\t[--separate-post-stats]\n" #ifdef HAVE_SSL "\t[--ssl] [--ssl-ciphers L] [--ssl-no-reuse]\n" #endif "\t[--stats-interval N] [--think-timeout X] [--timeout X]\n" //"\t[--uri S]" #ifdef HAVE_SCHED_AFFINITY "\t[--use-cpu-mask [0x]N]" #endif " [--verbose] [--version]\n" //"\t[--wlog y|n,file] [--wsess N,N,X]\n" "\t[--videosesslog [file1,file2,...],[perc1,perc2...],[local-ip1,local-ip2,...] \n" "\t[--num-sessions N] \n" "\t[--output-log file\n", //"\t[--wset N,X]\n", prog_name); } void panic (const char *msg, ...) { va_list va; va_start (va, msg); vfprintf (stderr, msg, va); va_end (va); exit (1); } void no_op (void) { } static void perf_sample (Timer *t, Any_Type regarg) { Any_Type callarg; callarg.d = 1.0 / (timer_now () - perf_sample_start); event_signal (EV_PERF_SAMPLE, 0, callarg); /* prepare for next sample interval: */ perf_sample_start = timer_now (); timer_schedule (perf_sample, regarg, param.rate_interval); } static void dump_stats (Timer *t, Any_Type regarg) { Any_Type callarg; getrusage (RUSAGE_SELF, &test_rusage_stop); // aansaarii: required to measure CPU utilization event_signal (EV_DUMP_STATS, 0, callarg); /* prepare for next sample interval: */ dump_stats_start = timer_now (); timer_schedule (dump_stats, regarg, param.stats_interval); } // Print stack trace on segfault void sigsegv_handler(int sig) { void *array[128]; size_t size; size = backtrace(array, 128); fprintf(stderr, "Backtrace:\n"); backtrace_symbols_fd(array, size, STDERR_FILENO); exit(1); } int main (int argc, char **argv) { // Register segfault handler signal(SIGSEGV, sigsegv_handler); #ifndef SRINI_RATE int numRates = 0; #endif extern Load_Generator conn_rate, call_seq; extern Load_Generator videosesslog, sess_cookie, misc; extern Stat_Collector stats_basic, session_stat; extern Stat_Collector stats_print_reply; extern char *optarg; int session_workload = 0; int num_gen = 3; int got_client_param = 0; Load_Generator *gen[5] = { &call_seq, &conn_rate, }; int num_stats = 1; Stat_Collector *stat[3] = { &stats_basic }; int i, ch, longindex; u_int minor, major; char *end, *name; Any_Type arg; void *flag; Time t; char hostname[MAX_HOSTNAME_LEN]; struct tm *local = 0; time_t local_t; printf("sizeof(fd_set) = %lu\n", (unsigned long) sizeof(fd_set)); #ifdef __FreeBSD__ /* This works around a bug in earlier versions of FreeBSD that cause non-finite IEEE arithmetic to cause SIGFPE instead of the non-finite arithmetic as defined by IEEE. */ fpsetmask (0); #endif object_type_size[OBJ_CONN] = sizeof (Conn); object_type_size[OBJ_CALL] = sizeof (Call); #ifdef HAVE_SCHED_AFFINITY param.cpu_mask = 0xffffffff; /* use any CPU */ #endif param.http_version = 0x10001; /* default to HTTP/1.1 */ param.client.id = 0; param.client.num_clients = 1; #ifdef UW_STABLE_STATS param.client.stagger_start = 0; param.ramp_up_conns = 0; param.ramp_down_conns = 0; #endif /* UW_STABLE_STATS */ param.server = "localhost"; param.port = -1; param.uri = "/"; param.num_calls = 1; param.burst_len = 1; param.num_conns = 1; /* These should be set to the minimum of 2*bandwidth*delay and the maximum request/reply size for single-call connections. */ param.send_buffer_size = 4096; param.recv_buffer_size = 16384; param.rate.dist = DETERMINISTIC; param.rate_interval = RATE_INTERVAL; param.stats_interval = STATS_INTERVAL; // aansaarii param.spec_stats = 0; #ifdef UW_CALL_STATS param.call_stats = -1; param.call_stats_file = ""; #endif param.separate_post_stats = 0; #ifdef HAVE_SSL param.ssl_reuse = 1; #endif param.num_sessions = 0; /* get program name: */ prog_name = strrchr (argv[0], '/'); if (prog_name) ++prog_name; else prog_name = argv[0]; /* process command line options: */ while ((ch = getopt_long (argc, argv, "d:hvV", longopts, &longindex)) >= 0) { switch (ch) { case 0: flag = longopts[longindex].flag; if (flag == ¶m.method) param.method = optarg; else if (flag == ¶m.additional_header) param.additional_header = optarg; else if (flag == ¶m.num_calls) { errno = 0; param.num_calls = strtoul (optarg, &end, 10); if (errno == ERANGE || end == optarg || *end) { fprintf (stderr, "%s: illegal number of calls %s\n", prog_name, optarg); exit (1); } } else if (flag == ¶m.http_version) { if (sscanf (optarg, "%u.%u", &major, &minor) != 2) { fprintf (stderr, "%s: illegal version number %s\n", prog_name, optarg); exit (1); } param.http_version = (major << 16) | (minor & 0xffff); } else if (flag == ¶m.burst_len) { errno = 0; param.burst_len = strtoul (optarg, &end, 10); if (errno == ERANGE || end == optarg || *end || param.burst_len < 1) { fprintf (stderr, "%s: illegal burst-length %s\n", prog_name, optarg); exit (1); } } else if (flag == ¶m.failure_status) { errno = 0; param.failure_status = strtoul (optarg, &end, 10); if (errno == ERANGE || end == optarg || *end || param.failure_status <= 0) { fprintf (stderr, "%s: illegal failure status %s\n", prog_name, optarg); exit (1); } } else if (flag == ¶m.num_conns) { errno = 0; param.num_conns = strtoul (optarg, &end, 10); if (errno == ERANGE || end == optarg || *end) { fprintf (stderr, "%s: illegal number of connections %s\n", prog_name, optarg); exit (1); } } else if (flag == ¶m.max_conns) { errno = 0; param.max_conns = strtoul (optarg, &end, 10); if (errno == ERANGE || end == optarg || *end || param.max_conns < 0) { fprintf (stderr, "%s: illegal max. # of connection %s\n", prog_name, optarg); exit (1); } } #ifdef IDLECONN else if (flag == ¶m.idle_conns) { errno = 0; param.idle_conns = strtoul (optarg, &end, 10); if (errno == ERANGE || end == optarg || *end || param.idle_conns < 0) { fprintf (stderr, "%s: illegal idle. # of connection %s\n", prog_name, optarg); exit (1); } } else if (flag == ¶m.idleconn) { param.idleconn = optarg; } #endif /* IDLECONN */ else if (flag == ¶m.max_piped) { errno = 0; param.max_piped = strtoul (optarg, &end, 10); if (errno == ERANGE || end == optarg || *end || param.max_piped < 0) { fprintf (stderr, "%s: illegal max. # of piped calls %s\n", prog_name, optarg); exit (1); } } else if (flag == ¶m.port) { errno = 0; param.port = strtoul (optarg, &end, 10); if (errno == ERANGE || end == optarg || *end || (unsigned) param.port > 0xffff) { fprintf (stderr, "%s: illegal port number %s\n", prog_name, optarg); exit (1); } } else if (flag == ¶m.lb_ports) { errno = 0; name = "bad server port (1st param)"; param.lb_ports.port[param.lb_ports.num_ports++] = strtoul (optarg, &end, 0); if (end == optarg || errno == ERANGE) goto bad_lb_port_param; optarg = end + 1; name = "bad server port (subsequent param)"; while ((*end == ',')&&(param.lb_ports.num_ports < MAX_SVR_PORTS)) { optarg = end + 1; param.lb_ports.port[param.lb_ports.num_ports++] = strtoul (optarg, &end, 0); if (end == optarg || errno == ERANGE) goto bad_lb_port_param; } if (*end) { bad_lb_port_param: fprintf (stderr, "%s: %s in --lb-port arg (rest: `%s')", prog_name, name, end); if (errno) fprintf (stderr, ": %s", strerror (errno)); fputc ('\n', stderr); exit (1); } } else if (flag == ¶m.print_request || flag == ¶m.print_reply) { int val; if (!optarg) val = PRINT_HEADER | PRINT_BODY; else switch (tolower (optarg[0])) { case 'h': val = PRINT_HEADER; break; case 'b': val = PRINT_BODY; break; default: val = PRINT_HEADER | PRINT_BODY; break; } *(int *) flag = val; } else if (flag == ¶m.rate) { errno = 0; param.rate.rate_param = strtod (optarg, &end); if (errno == ERANGE || end == optarg || *end) { fprintf (stderr, "%s: illegal request rate %s\n", prog_name, optarg); exit (1); } if (param.rate.rate_param <= 0.0) param.rate.mean_iat = 0.0; else param.rate.mean_iat = 1/param.rate.rate_param; param.rate.dist = DETERMINISTIC; } else if (flag == ¶m.rate_interval) { errno = 0; param.rate_interval = strtod(optarg,&end); if (errno == ERANGE || end == optarg || *end) { fprintf (stderr, "%s: illegal request rate %s\n", prog_name, optarg); exit (1); } else if ( param.rate_interval < 0.0 ) { fprintf(stderr, "Rate interval must be positive floating point value!\n"); exit(1); } } else if (flag == ¶m.rate.mean_iat) /* --period */ { param.rate.dist = DETERMINISTIC; if (!isdigit (*optarg)) switch (tolower(*optarg++)) { case 'd': param.rate.dist = DETERMINISTIC; break; case 'u': param.rate.dist = UNIFORM; break; case 'e': param.rate.dist = EXPONENTIAL; break; #ifndef SRINI_RATE case 'v': param.rate.dist = VARIABLE; break; case 'l': param.rate.dist = VARIABLE_EXP; break; #endif default: fprintf (stderr, "%s: illegal interarrival distribution " "'%c' in %s\n", prog_name, optarg[-1], optarg - 1); exit (1); } /* remaining params depend on selected distribution: */ errno = 0; switch (param.rate.dist) { case DETERMINISTIC: case EXPONENTIAL: param.rate.mean_iat = strtod (optarg, &end); if (errno == ERANGE || end == optarg || *end || param.rate.mean_iat < 0) { fprintf (stderr, "%s: illegal mean interarrival " "time %s\n", prog_name, optarg); exit (1); } break; case UNIFORM: param.rate.min_iat = strtod (optarg, &end); if (errno == ERANGE || end == optarg || param.rate.min_iat < 0) { fprintf (stderr, "%s: illegal minimum interarrival " "time %s\n", prog_name, optarg); exit (1); } if (*end != ',') { fprintf (stderr, "%s: minimum interarrival time not " "followed by `,MAX_IAT' (rest: `%s')\n", prog_name, end); exit (1); } optarg = end + 1; param.rate.max_iat = strtod (optarg, &end); if (errno == ERANGE || end == optarg || *end || param.rate.max_iat < 0) { fprintf (stderr, "%s: illegal request period %s\n", prog_name, optarg); exit (1); } param.rate.mean_iat = 0.5*(param.rate.min_iat + param.rate.max_iat); break; #ifndef SRINI_RATE case VARIABLE: case VARIABLE_EXP: while (1) { param.rate.iat[numRates] = strtod (optarg, &end); if (errno == ERANGE || end == optarg || param.rate.iat[numRates] < 0) { fprintf (stderr, "%s: illegal minimum interarrival " "time %s\n", prog_name, optarg); exit (1); } if (*end != ',') { fprintf (stderr, "%s: inter-arrival time not " "followed by `,duration' (rest: `%s')\n", prog_name, end); exit (1); } optarg = end + 1; param.rate.duration[numRates] = strtod (optarg, &end); if (errno == ERANGE || end == optarg || param.rate.duration[numRates] < 0) { fprintf (stderr, "%s: illegal duration %s\n", prog_name, optarg); exit (1); } if (numRates == 0) param.rate.mean_iat = param.rate.iat[numRates]; else param.rate.mean_iat += param.rate.iat[numRates]; numRates ++; if (*end != ',') { param.rate.numRates = numRates; break; } else optarg = end + 1; } param.rate.mean_iat /= numRates; break; #endif default: fprintf (stderr, "%s: internal error parsing %s\n", prog_name, optarg); exit (1); break; } param.rate.rate_param = ((param.rate.mean_iat <= 0.0) ? 0.0 : (1.0 / param.rate.mean_iat)); } else if (flag == ¶m.recv_buffer_size) { errno = 0; param.recv_buffer_size = strtoul (optarg, &end, 10); if (errno == ERANGE || end == optarg || *end || param.port > 0xffff) { fprintf (stderr, "%s: illegal receive buffer size %s\n", prog_name, optarg); exit (1); } } else if (flag == ¶m.send_buffer_size) { errno = 0; param.send_buffer_size = strtoul (optarg, &end, 10); if (errno == ERANGE || end == optarg || *end || param.port > 0xffff) { fprintf (stderr, "%s: illegal send buffer size %s\n", prog_name, optarg); exit (1); } } else if (flag == ¶m.client) { got_client_param = 1; errno = 0; param.client.id = strtoul (optarg, &end, 0); if (end == optarg || errno == ERANGE) { fprintf (stderr, "%s: bad client id (rest: `%s')\n", prog_name, optarg); exit (1); } if (*end != '/') { fprintf (stderr, "%s: client id not followed by `/' (rest: `%s')\n", prog_name, end); exit (1); } optarg = end + 1; param.client.num_clients = strtoul (optarg, &end, 0); if (end == optarg || errno == ERANGE || param.client.id >= param.client.num_clients) { fprintf (stderr, "%s: bad number of clients (rest: `%s')\n", prog_name, optarg); exit (1); } } else if (flag == ¶m.server) param.server = optarg; else if (flag == ¶m.server_name) param.server_name = optarg; else if (flag == ¶m.output_log) param.output_log = optarg; #ifdef HAVE_SSL else if (flag == ¶m.ssl_cipher_list) param.ssl_cipher_list = optarg; #endif else if (flag == ¶m.stats_interval) { errno = 0; param.stats_interval = strtoul (optarg, &end, 10); if (errno == ERANGE || end == optarg || *end) { fprintf (stderr, "%s: illegal statistics interval length" " %s\n", prog_name, optarg); exit (1); } } #ifdef UW_CALL_STATS else if (flag == ¶m.call_stats) { param.call_stats = atoi(optarg); printf("%s: Collecting call stats buffer size = %d\n", prog_name, param.call_stats); } else if (flag == ¶m.call_stats_file) { param.call_stats_file = strdup( optarg ); printf("%s: file sizes from = %s\n", prog_name, param.call_stats_file); } #endif else if (flag == ¶m.uri) param.uri = optarg; else if (flag == ¶m.think_timeout) { errno = 0; param.think_timeout = strtod (optarg, &end); if (errno == ERANGE || end == optarg || *end) { fprintf (stderr, "%s: illegal think timeout value %s\n", prog_name, optarg); exit (1); } } else if (flag == ¶m.timeout) { errno = 0; param.timeout = strtod (optarg, &end); if (errno == ERANGE || end == optarg || *end) { fprintf (stderr, "%s: illegal connect timeout %s\n", prog_name, optarg); exit (1); } } /* else if (flag == ¶m.wlog) { gen[1] = &uri_wlog; // XXX fix me---somehow param.wlog.do_loop = (*optarg == 'y') || (*optarg == 'Y'); param.wlog.file = optarg + 2; } else if (flag == ¶m.wsess) { num_gen = 2; // XXX fix me---somehow gen[0] = &wsess; stat[num_stats++] = &session_stat; errno = 0; name = "bad number of sessions (1st param)"; param.wsess.num_sessions = strtoul (optarg, &end, 0); if (end == optarg || errno == ERANGE) goto bad_wsess_param; optarg = end + 1; name = "bad number of calls per session (2nd param)"; if (*end != ',') goto bad_wsess_param; optarg = end + 1; param.wsess.num_calls = strtoul (optarg, &end, 0); if (end == optarg || errno == ERANGE) goto bad_wsess_param; name = "bad user think time (3rd param)"; if (*end != ',') goto bad_wsess_param; optarg = end + 1; param.wsess.think_time = strtod (optarg, &end); if (end == optarg || errno == ERANGE || param.wsess.think_time < 0.0) goto bad_wsess_param; name = "extraneous parameter"; if (*end) { bad_wsess_param: fprintf (stderr, "%s: %s in --wsess arg (rest: `%s')", prog_name, name, end); if (errno) fprintf (stderr, ": %s", strerror (errno)); fputc ('\n', stderr); exit (1); } session_workload = 1; } else if (flag == ¶m.wsesspage) { num_gen = 2; // XXX fix me---somehow gen[0] = &wsesspage; stat[num_stats++] = &session_stat; errno = 0; name = "bad number of sessions (1st param)"; param.wsesspage.num_sessions = strtoul (optarg, &end, 0); if (end == optarg || errno == ERANGE) goto bad_wsesspage_param; optarg = end + 1; name = "bad number of user requests per session (2nd param)"; if (*end != ',') goto bad_wsesspage_param; optarg = end + 1; param.wsesspage.num_reqs = strtoul (optarg, &end, 0); if (end == optarg || errno == ERANGE) goto bad_wsesspage_param; name = "bad user think time (3rd param)"; if (*end != ',') goto bad_wsesspage_param; optarg = end + 1; param.wsesspage.think_time = strtod (optarg, &end); if (end == optarg || errno == ERANGE || param.wsesspage.think_time < 0.0) goto bad_wsesspage_param; name = "extraneous parameter"; if (*end) { bad_wsesspage_param: fprintf (stderr, "%s: %s in --wsesspage arg (rest: `%s')", prog_name, name, end); if (errno) fprintf (stderr, ": %s", strerror (errno)); fputc ('\n', stderr); exit (1); } session_workload = 1; } */ else if (flag == ¶m.videosesslog) { char file_list[5*1024]; char req_mix_list[1024]; char local_ip_list[1024]; char *tmp; int end_index = -1, i=0, j=0, k=0; char delim[2] = ","; char* token = NULL; num_gen = 1; // XXX fix me---somehow gen[0] = &videosesslog; stat[num_stats++] = &session_stat; errno = 0; /* name = "bad number of sessions (1st param)"; param.videosesslog.num_sessions = strtoul (optarg, &end, 0); if (end == optarg || errno == ERANGE) goto bad_videosesslog_param; optarg = end + 1; name = "bad user think time (2nd param)"; if (*end != ',') goto bad_videosesslog_param; optarg = end + 1; param.videosesslog.think_time = strtod (optarg, &end); if (end == optarg || errno == ERANGE || param.videosesslog.think_time < 0.0) goto bad_videosesslog_param; if (*end != ',') goto bad_videosesslog_param; optarg = end + 1; */ name = "bad session file-list (1st param)"; /* Read the file-list and perc-list Identify the indices correctly The file-list is in [file1, file2, file3...] The req-mix is in [perc1, perc2, perc3, ...] */ if (*optarg != '[') goto bad_videosesslog_param; optarg++; tmp = strchr(optarg, ']'); end_index = (int)(tmp - optarg); strncpy(file_list, optarg, end_index); file_list[end_index] = '\0'; // Tokenize the files token = strtok(file_list, delim); while(token != NULL) { if (i >= MAX_LOG_FILES) { name = "Maximum number of log files is 4."; goto bad_videosesslog_param; } strcpy(param.videosesslog.file[i++], token); token = strtok(NULL, delim); } end = optarg+end_index+1; name = "bad request mix percentage (2nd param)"; if (*end != ',') goto bad_videosesslog_param; optarg = end + 1; if (*optarg != '[') goto bad_videosesslog_param; optarg++; tmp = strchr(optarg, ']'); end_index = (int)(tmp - optarg); strncpy(req_mix_list, optarg, end_index); token = strtok(req_mix_list, delim); while (token != NULL) { if (j >= MAX_LOG_FILES) { name = "Maximum number of log files is 4."; goto bad_videosesslog_param; } param.videosesslog.sess_perc[j++] = strtod(token, NULL); if (errno == ERANGE) goto bad_videosesslog_param; token = strtok(NULL, delim); } name = "Mismatch in number of files and request mix"; if (i != j) goto bad_videosesslog_param; end = optarg+end_index+1; param.videosesslog.num_logs = i; if (*end == '\0') goto skip_local_ip_param; name = "Bad local-ips (5th parameters)"; if (*end == ',') { // There are local-ips specified optarg = end + 1; if (*optarg != '[') goto bad_videosesslog_param; optarg++; tmp = strchr(optarg, ']'); end_index = (int)(tmp - optarg); strncpy(local_ip_list, optarg, end_index); token = strtok(local_ip_list, delim); while (token != NULL) { if (k >= MAX_LOG_FILES) { name = "Maximum number of log files is 4."; goto bad_videosesslog_param; } strcpy(param.videosesslog.local_ip[k++], token); token = strtok(NULL, delim); } name = "Mismatch in number of log files and local-ips specified."; if (i != k) goto bad_videosesslog_param; } end = optarg+end_index+1; name = "extraneous parameter"; if (*end) { bad_videosesslog_param: fprintf (stderr, "%s: %s in --videosesslog arg (rest: `%s')", prog_name, name, end); if (errno) fprintf (stderr, ": %s", strerror (errno)); fputc ('\n', stderr); exit (1); } skip_local_ip_param: session_workload = 1; } else if (flag == ¶m.num_sessions) { param.num_sessions = strtoul (optarg, &end, 0); } /* else if (flag == ¶m.wset) { gen[1] = &uri_wset; // XXX fix me---somehow errno = 0; name = "bad working set size (1st parameter)"; param.wset.num_files = strtoul (optarg, &end, 0); if (end == optarg || errno == ERANGE) goto bad_wset_param; name = "bad target miss rate (2nd parameter)"; if (*end != ',') goto bad_wset_param; optarg = end + 1; param.wset.target_miss_rate = strtod (optarg, &end); if (end == optarg || errno == ERANGE || param.wset.target_miss_rate < 0.0 || param.wset.target_miss_rate > 1.0) goto bad_wset_param; name = "extraneous parameter"; if (*end) { bad_wset_param: fprintf (stderr, "%s: %s in --wset arg (rest: `%s')", prog_name, name, optarg); if (errno) fprintf (stderr, ": %s", strerror (errno)); fputc ('\n', stderr); exit (1); } } */ #ifdef HAVE_SCHED_AFFINITY else if (flag == ¶m.cpu_mask) { errno = 0; if (!strncmp(optarg, "0x", 2)) param.cpu_mask = strtoul (optarg, &end, 16); else param.cpu_mask = strtoul (optarg, &end, 10); if (errno == ERANGE || end == optarg || *end) { fprintf (stderr, "%s: illegal CPU mask %s\n", prog_name, optarg); exit (1); } } #endif /* HAVE_SCHED_AFFINITY */ #ifdef UW_STABLE_STATS else if (flag == ¶m.ramp_up_conns) { errno = 0; param.ramp_up_conns = strtod (optarg, &end); if (errno == ERANGE || end == optarg || *end) { fprintf (stderr, "%s: illegal number of connections %s\n", prog_name, optarg); exit (1); } } else if (flag == ¶m.ramp_down_conns) { errno = 0; param.ramp_down_conns = strtod (optarg, &end); if (errno == ERANGE || end == optarg || *end) { fprintf (stderr, "%s: illegal number of connections %s\n", prog_name, optarg); exit (1); } } #endif /* UW_STABLE_STATS */ break; case 'd': #ifdef DEBUG errno = 0; debug_level = strtoul (optarg, &end, 10); if (errno == ERANGE || end == optarg || *end) { fprintf (stderr, "%s: illegal debug level %s\n", prog_name, optarg); exit (1); } #else fprintf (stderr, "%s: sorry, need to recompile with -DDEBUG on...\n", prog_name); #endif break; case 'v': ++verbose; break; case 'V': printf ("%s: httperf-"VERSION" compiled "__DATE__" with" #ifndef DEBUG "out" #endif " DEBUG with" #ifndef TIME_SYSCALLS "out" #endif " TIME_SYSCALLS.\n", prog_name); // Can't exit here, trun uses -V for all runs // exit(0); break; case 'h': usage (); exit (0); case ':': fprintf (stderr, "%s: parameter missing for option %s\n", prog_name, longopts[longindex].name); exit (1); case '?': /* Invalid or ambiguous option name or extraneous parameter. getopt_long () already issued an explanation to the user, so all we do is call it quites. */ exit (1); default: fprintf (stderr, "%s: getopt_long: unexpected value (%d)\n", prog_name, ch); exit (1); } } if (param.num_sessions <= 0) { fprintf(stderr, "Num_sessions: invalid value %d\n", param.num_sessions); exit(-1); } #ifdef HAVE_SSL /* videosesslog may have some sessions which use ssl */ if (param.use_ssl || param.num_sessions) { char buf[1024]; if (param.port < 0) param.port = 443; SSL_load_error_strings (); SSLeay_add_ssl_algorithms (); /* for some strange reason, SSLv23_client_method () doesn't work here */ SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_3_VERSION); ssl_ctx = SSL_CTX_new (TLS_client_method ()); if (!ssl_ctx) { ERR_print_errors_fp (stderr); exit (-1); } memset (buf, 0, sizeof (buf)); RAND_seed (buf, sizeof (buf)); } #endif if (param.port < 0) param.port = 80; if (param.print_reply || param.print_request) stat[num_stats++] = &stats_print_reply; if (param.session_offsets) { if (!got_client_param) { printf("Can't use --client-session-offsets without --client I/N\n"); exit(1); } } if (param.session_cookies) { if (!session_workload) { fprintf (stderr, "%s: --session-cookie requires session-oriented " "workload (e.g., --wsess)\n", prog_name); exit (-1); } gen[num_gen++] = &sess_cookie; } if (param.additional_header || param.method) gen[num_gen++] = &misc; /* echo command invocation for logging purposes: */ printf ("%s", prog_name); if (verbose) printf (" --verbose"); switch (param.print_reply) { case 0: break; case PRINT_HEADER: printf (" --print-reply=header"); break; case PRINT_BODY: printf (" --print-reply=body"); break; default: printf (" --print-reply"); break; } switch (param.print_request) { case 0: break; case PRINT_HEADER: printf (" --print-request=header"); break; case PRINT_BODY: printf (" --print-request=body"); break; default: printf (" --print-request"); break; } if (param.hog) printf (" --hog"); if (param.close_with_reset) printf (" --close-with-reset"); if (param.timeout_with_reset) printf (" --timeout-with-reset"); if (param.think_timeout > 0) printf (" --think-timeout=%g", param.think_timeout); if (param.timeout > 0) printf (" --timeout=%g", param.timeout); printf (" --client=%u/%u", param.client.id, param.client.num_clients); if (param.server) printf (" --server=%s", param.server); if (param.server_name) printf (" --server_name=%s", param.server_name); if (param.port) printf (" --port=%d", param.port); if (param.uri) printf (" --uri=%s", param.uri); if (param.failure_status) printf (" --failure-status=%u", param.failure_status); if (param.http_version != 0x10001) printf (" --http-version=%u.%u", param.http_version >> 16, param.http_version & 0xffff); if (param.max_conns) printf (" --max-connections=%u", param.max_conns); #ifdef IDLECONN if (param.idle_conns) printf (" --idle-connections=%u", param.idle_conns); if (param.idleconn) printf (" --idleconn=%s", param.idleconn); #endif /* IDLECONN */ if (param.max_piped) printf (" --max-piped-calls=%u", param.max_piped); if (param.rate_interval != 5.0) printf("--rate-interval=%g", param.rate_interval); if (param.rate.rate_param > 0.0) { switch (param.rate.dist) { case DETERMINISTIC: /* for backwards compatibility, continue to use --rate: */ printf (" --rate=%g", param.rate.rate_param); break; case UNIFORM: printf (" --period=u%g,%g", param.rate.min_iat, param.rate.max_iat); break; case EXPONENTIAL: printf (" --period=e%g", param.rate.mean_iat); break; #ifndef SRINI_RATE case VARIABLE: case VARIABLE_EXP: { int m; printf (" --period=%c", (param.rate.dist == VARIABLE) ? 'v' : 'l'); for (m=0; m 0) { printf (" --ramp-up-num-conns=%d", param.ramp_up_conns ); } if (param.ramp_down_conns > 0) { printf (" --ramp-down-num-conns=%d", param.ramp_down_conns ); } #endif /* UW_STABLE_STATS */ printf (" --send-buffer=%d", param.send_buffer_size); if (param.retry_on_failure) printf (" --retry-on-failure"); printf (" --recv-buffer=%d", param.recv_buffer_size); if (param.session_cookies) printf (" --session-cookies"); #ifdef HAVE_EPOLL if (param.use_epoll) printf (" --epoll"); #endif #ifdef HAVE_SSL if (param.use_ssl) printf (" --ssl"); if (param.ssl_cipher_list) printf(" --ssl-ciphers=%s", param.ssl_cipher_list); if (!param.ssl_reuse) printf (" --ssl-no-reuse"); #endif #ifdef UW_CALL_STATS if (param.call_stats != -1) printf (" --call-stats=%d", param.call_stats); if (param.call_stats_file != 0) printf (" --call-stats-file=%s", param.call_stats_file); #endif if (param.stats_interval) printf (" --stats-interval=%d", param.stats_interval); if (param.additional_header) printf (" --add-header='%s'", param.additional_header); if (param.method) printf (" --method=%s", param.method); if (param.num_sessions) { /* This overrides any --wsess, --num-conns, --num-calls, --burst-length and any uri generator */ // TODO printf (" --videosesslog=%u,%.3f,%s", param.videosesslog.num_sessions, // param.videosesslog.think_time, param.videosesslog.file); } /* else if (param.wsesspage.num_sessions) { printf (" --wsesspage=%u,%u,%.3f", param.wsesspage.num_sessions, param.wsesspage.num_reqs, param.wsesspage.think_time); } else { if (param.wsess.num_sessions) printf (" --wsess=%u,%u,%.3f", param.wsess.num_sessions, param.wsess.num_calls, param.wsess.think_time); else { if (param.num_conns) printf (" --num-conns=%d", param.num_conns); if (param.num_calls) printf (" --num-calls=%d", param.num_calls); } if (param.burst_len != 1) printf (" --burst-length=%d", param.burst_len); if (param.wset.num_files) printf (" --wset=%u,%.3f", param.wset.num_files, param.wset.target_miss_rate); } */ printf ("\n"); gethostname(hostname, MAX_HOSTNAME_LEN-1); printf("Run on hostname: %s\n", hostname); local_t = time(NULL); local = localtime(&local_t); printf("Run at: %s\n", asctime(local)); #ifdef HAVE_SCHED_AFFINITY { int rc; unsigned long cpu_mask; if (param.cpu_mask != 0xffffffff) { rc = sched_setaffinity_videoperf (0, sizeof(param.cpu_mask), ¶m.cpu_mask); if (rc < 0) { fprintf (stderr, "%s: sched_setaffinity failed, rc=%d errno=%d (%s)\n", prog_name, rc, errno, strerror(errno)); exit (1); } rc = sched_getaffinity_videoperf (0, sizeof(cpu_mask), &cpu_mask); if (rc < 0) { fprintf (stderr, "%s: sched_getaffinity failed, rc=%d errno=%d (%s)\n", prog_name, rc, errno, strerror(errno)); exit (1); } printf("Effective CPU mask: 0x%lx\n", cpu_mask); } } #endif /* HAVE_SCHED_AFFINITY */ #ifdef IDLECONN int idlepid = 0; if (param.idle_conns) { idlepid = fork(); if (idlepid < 0) { fprintf (stderr, "%s: could not fork idleconn process\n", prog_name); exit(1); } else if (idlepid == 0) { // fork: idleconn server port numidle char iconn[100]; sprintf(iconn, "%u", param.idle_conns); char iport[100]; sprintf(iport, "%u", param.port); char icmd[1000]; if (param.idleconn) { strcpy(icmd, param.idleconn); } else { strcpy(icmd, "idleconn"); } int res = execlp(icmd, icmd, param.server, iport, iconn, NULL); if (res != 0) { printf("res = %d\n", errno); fprintf (stderr, "%s: could not exec %s process\n", prog_name, icmd); exit(1); } } } #endif /* IDLECONN */ timer_init (); core_init (); signal (SIGINT, (void (*)()) core_exit); for (i = 0; i < num_stats; ++i) (*stat[i]->init)(); for (i = 0; i < num_gen; ++i) (*gen[i]->init) (); /* Update `now'. This is to keep things accurate even when some of the initialization routines take a long time to execute. */ timer_tick (); /* ensure that clients sample rates at different times: */ t = (param.client.id + 1.0)*param.rate_interval/param.client.num_clients; arg.l = 0; timer_schedule (perf_sample, arg, t); perf_sample_start = timer_now (); if (param.stats_interval) { timer_schedule (dump_stats, arg, t); dump_stats_start = timer_now (); } #ifdef OLDWAY /* We believe this is needed for staggered starts */ /* There might be a different/better way to do this */ /* setting test time here because it is used when starting stats */ test_time_start = timer_now (); #endif /* OLDWAY */ for (i = 0; i < num_gen; ++i) (*gen[i]->start) (); for (i = 0; i < num_stats; ++i) (*stat[i]->start)(); getrusage (RUSAGE_SELF, &test_rusage_start); test_time_start = timer_now (); core_loop (); test_time_stop = timer_now (); getrusage (RUSAGE_SELF, &test_rusage_stop); for (i = 0; i < num_stats; ++i) (*stat[i]->stop)(); for (i = 0; i < num_gen; ++i) (*gen[i]->stop) (); for (i = 0; i < num_stats; ++i) (*stat[i]->dump)(); #if IDLECONN if (idlepid > 0) kill(idlepid, SIGINT); #endif /* IDLECONN */ return 0; } ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/httperf.h ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef httperf_h #define httperf_h #include "config.h" #include #include #include #include "sys_sched_affinity.h" #define VERSION "0.8.6c" typedef double Time; #define NELEMS(a) ((sizeof (a)) / sizeof ((a)[0])) #define TV_TO_SEC(tv) ((tv).tv_sec + 1e-6*(tv).tv_usec) #ifndef SRINI_RATE #define NUM_RATES 10 #endif #define MAX_LOG_FILES 4 typedef union { char c; int i; long l; u_char uc; u_int ui; u_long ul; float f; double d; void *vp; const void *cvp; } Any_Type; typedef enum Dist_Type { DETERMINISTIC, /* also called fixed-rate */ UNIFORM, /* over interval [min_iat,max_iat) */ #ifndef SRINI_RATE VARIABLE, /* allows varying input load */ VARIABLE_EXP, /* varying input load with exponential distribution */ #endif EXPONENTIAL /* with mean mean_iat */ } Dist_Type; typedef struct Load_Generator { const char *name; void (*init) (void); void (*start) (void); void (*stop) (void); } Load_Generator; typedef struct Stat_Collector { const char *name; /* START and STOP are timing sensitive, so they should be as short as possible. More expensive stuff can be done during INIT and DUMP. */ void (*init) (void); void (*start) (void); void (*stop) (void); void (*dump) (void); } Stat_Collector; typedef struct Rate_Info { Dist_Type dist; /* interarrival distribution */ double rate_param; /* 0 if mean_iat==0, else 1/mean_iat */ Time mean_iat; /* mean interarrival time */ Time min_iat; /* min interarrival time (for UNIFORM) */ Time max_iat; /* max interarrival time (for UNIFORM) */ #ifndef SRINI_RATE int numRates; /* number of rates we want to use */ Time iat[NUM_RATES]; Time duration[NUM_RATES]; #endif } Rate_Info; #define PRINT_HEADER (1 << 0) #define PRINT_BODY (1 << 1) #define MAX_SVR_PORTS 16 typedef struct Cmdline_Params { unsigned long cpu_mask; /* mask of schedulable CPUs (if supported) */ int http_version; /* (default) HTTP protocol version */ const char *server; /* (default) hostname */ const char *server_name; /* fully qualified server name */ char* output_log; int port; /* (default) server port */ const char *uri; /* (default) uri */ Rate_Info rate; Time timeout; /* watchdog timeout */ Time think_timeout; /* timeout for server think time */ #ifdef HAVE_EPOLL int use_epoll; /* use epoll instead of select */ #endif int num_conns; /* # of connections to generate */ int num_calls; /* # of calls to generate per connection */ int burst_len; /* # of calls to burst back-to-back */ int max_piped; /* max # of piped calls per connection */ int max_conns; /* max # of connections per session */ #ifdef IDLECONN int idle_conns; /* idle # of connections per session */ char* idleconn; /* idleconn binary path */ #endif /* IDLECONN */ int hog; /* client may hog as much resources as possible */ int send_buffer_size; int recv_buffer_size; int failure_status; /* status code that should be considered failure */ int retry_on_failure; /* when a call fails, should we retry? */ int close_with_reset; /* close connections with TCP RESET? */ int timeout_with_reset; /* one timeout close connections with TCP RESET? */ int print_request; /* bit 0: print req headers, bit 1: print req body */ int print_reply; /* bit 0: print repl headers, bit 1: print repl body */ int session_cookies; /* handle set-cookies? (at the session level) */ int no_host_hdr; /* don't send Host: header in request */ int stats_interval; /* print summary statistics every N seconds */ int spec_stats; /* Should we gather SPECweb99 specific statistics? */ #ifdef UW_CALL_STATS int call_stats; /* Should we gather call specific statistics? */ char *call_stats_file; /* file containing file sizes used for call_stats */ #endif /* UW_CALL_STATS */ int separate_post_stats; /* Should we separate stats for dyanmic POST requests? */ int verify_reply; /* Should we verify (i.e. check the bytes of) SPECweb99 replies*/ const char * verify_dir; /* Directory containing reference file set (for verification) */ double rate_interval; /* interval at which rate info is sampled */ #ifdef HAVE_SSL int use_ssl; /* connect via SSL */ int ssl_reuse; /* reuse SSL Session ID */ const char *ssl_cipher_list; /* client's list of SSL cipher suites */ #endif #ifdef UW_STABLE_STATS int ramp_up_conns; /* num of conns to ignore at beginning of experiment */ int ramp_down_conns; /* num of conns to ignore at end of experiment */ #endif /* UW_STABLE_STATS */ const char *additional_header; /* additional request header(s) */ const char *method; /* default call method */ int session_offsets; /* should each client start in a different position in the wsesslog file */ struct { u_int id; u_int num_clients; int stagger_start; } client; /* struct { char *file; // name of the file where entries are char do_loop; // boolean indicating if we want to loop on entries } wlog; struct { u_int num_sessions; // # of sessions u_int num_calls; // # of calls per session Time think_time; // user think time between calls } wsess; struct { u_int num_sessions; // # of sessions u_int num_reqs; // # of user requests per session Time think_time; // user think time between requests } wsesspage; struct { u_int num_sessions; // # of user-sessions Time think_time; // user think time between calls char *file; // name of the file where session defs are int exit_early; // exit early? } wsesslog; struct { u_int num_files; double target_miss_rate; } wset; */ struct { int cur_port; int num_ports; int port[MAX_SVR_PORTS]; } lb_ports; struct { u_int num_logs; /* # of session logs */ char file[MAX_LOG_FILES][1024]; /* File names of session logs */ double sess_perc[MAX_LOG_FILES]; /* Array of percentile for request-mix probability */ char local_ip[MAX_LOG_FILES][16]; /* The local-ip addresses to bind to. */ Time think_time; /* user think time between calls */ } videosesslog; u_int num_sessions; /* # of user-sessions */ } Cmdline_Params; extern const char *prog_name; extern int verbose; extern Cmdline_Params param; extern Time test_time_start; extern Time test_time_stop; extern struct rusage test_rusage_start; extern struct rusage test_rusage_stop; #ifdef HAVE_SSL # include extern SSL_CTX *ssl_ctx; #endif #ifdef DEBUG extern int debug_level; # define DBG debug_level #else # define DBG 0 #endif extern void panic (const char *msg, ...); extern void no_op (void); /* Connection problems encountered by httperf - that are a * result of a failed system call - so there is no errno to use * * Note: we depend on errno being positive values and these being negative */ #define CONN_ERR_NOT_SET (-1) #define CONN_ERR_NO_MORE_PORTS (-2) #define CONN_ERR_HASH_LOOKUP_FAILED (-3) #define CONN_ERR_STATE_PAST_CLOSING (-4) // How many entries needed in the array. #define CONN_ERR_COUNT (-CONN_ERR_STATE_PAST_CLOSING + 1) #endif /* httperf_h */ ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/httperf.man ================================================ .TH httperf 1 "30 Oct 2000" .IX httperf .SH NAME httperf \- HTTP performance measurement tool .SH SYNOPSIS .B httperf .RB [ --add-header .IR S ] .RB [ --burst-length .IR N ] .RB [ --client .IR I / N ] .RB [ --client-session-offsets ] .RB [ --close-with-reset ] .RB [ -d | --debug .IR N ] .RB [ --failure-status .IR N ] .RB [ -h | --help ] .RB [ --hog ] .RB [ --http-version .IR S ] .RB [ --max-connections .IR N ] .RB [ --max-piped-calls .IR N ] .RB [ --method .IR S ] .RB [ --no-host-hdr ] .RB [ --num-calls .IR N ] .RB [ --num-conns .IR N ] .RB [ --period " [" d | u | e ] \fIT1\fR [ ,\fIT2\fR ]] .RB [ --port .IR N ] .RB [ --print-reply " [" header | body ] ] .RB [ --print-request " [" header | body ] ] .RB [ --ramp-down-num-conns .IR N ] .RB [ --ramp-up-num-conns .IR N ] .RB [ --stagger-start ] .RB [ --call-stats .IR N ] .RB [ --spec-stats ] .RB [ --rate .IR X ] .RB [ --recv-buffer .IR N ] .RB [ --retry-on-failure ] .RB [ --send-buffer .IR N ] .RB [ --server .IR S ] .RB [ --server-name .IR S ] .RB [ --session-cookie ] .RB [ --ssl ] .RB [ --ssl-ciphers .IR L ] .RB [ --ssl-no-reuse ] .RB [ --think-timeout .IR X ] .RB [ --timeout .IR X ] .RB [ --uri .IR S ] .RB [ -v | --verbose ] .RB [ -V | --version ] .RB [ "--wlog y" | n, \fIF\fR] .RB [ --wsess .IR N , N , X ] .RB [ --wsesslog .IR N , X , F ] .RB [ --wset .IR N , X ] .SH DESCRIPTION .B httperf is a tool to measure web server performance. It speaks the HTTP protocol both in its HTTP/1.0 and HTTP/1.1 flavors and offers a variety of workload generators. While running, it keeps track of a number of performance metrics that are summarized in the form of statistics that are printed at the end of a test run. The most basic operation of .B httperf is to generate a fixed number of HTTP GET requests and to measure how many replies (responses) came back from the server and at what rate the responses arrived. .B IMPORTANT: To obtain correct results, it is necessary to run at most one .B httperf process per client machine. Also, there should be as few background processes as possible both on the client and server machines. .SH EXAMPLES .TP httperf --hog --server www This command causes .B httperf to create a connection to host www, send a request for the root document (http://www/), receive the reply, close the connection, and then print some performance statistics. .TP httperf --hog --server www --num-conn 100 --ra 10 --timeout 5 Like above, except that a total of 100 connections are created and that connections are created at a fixed rate of 10 per second. Note that option ``--rate'' has been abbreviated to ``--ra''. .TP httperf --hog --server=www --wsess=10,5,2 --rate 1 --timeout 5 Causes .B httperf to generate a total of 10 sessions at a rate of 1 session per second. Each session consists of 5 calls that are spaced out by 2 seconds. .TP httperf --hog --server=www --wsess=10,5,2 --rate=1 --timeout=5 --ssl Like above, except that .B httperf contacts server www via SSL at port 443 (the default port for SSL connections). .TP httperf --hog --server www --wsess=10,5,2 --rate=1 --timeout=5 --ssl --ssl-ciphers=EXP-RC4-MD5:EXP-RC2-CBC-MD5 --ssl-no-reuse --http-version=1.0 Like above, except that .B httperf will inform the server that it can only select from two cipher suites (EXP-RC4-MD5 or EXP-RC2-CBC-MD5); furthermore, .B httperf will use HTTP version 1.0 which requires a new TCP connection for each request. Also, SSL session ids are not reused, so the entire SSL connection establishment process (known as the SSL handshake) occurs for each connection. .SH OPTIONS The operation of .B httperf can be controlled through a number of options. The tool supports both short (one-character) and long (arbitrary-length) option names. Short options are prefixed with a single leading dash (-), long options with a double-dash (--). Multiple short options can be grouped together (e.g., .RB `` -vV '' is equivalent to .RB `` "-v -V" '') and long options can be abbreviated so long as they remain unique. Parameters to options can be specified either by following the long option name with an equal sign and the parameter value (e.g., .BR --burst=10 ) or by separating the option name and value with whitespace (e.g., .BR "--burst 10" ). .TP .BI --add-header= S Specifies to include string .I S as an additional request header. It is necessary to specify the terminating carriage-return/line-feed sequence explicitly. This can be done by using the escape sequence ``\\n''. This makes it possible to include multiple request headers. For example, ``--add-header "Referer: foo\\nAuth: secret\\n"'' would add two request headers (``Referer'' and ``Auth'') to each request. Other supported escape sequences are ``\\r'' (carriage-return), ``\\a'' (line-feed), ``\\\\'' (backslash), and ``\\N'' where N is the code the character to be inserted (in octal). .TP .BI --burst-length= N Specifies the length of bursts. Each burst consists of .I N calls to the server. The exact meaning of this parameter depends on the workload generator. For regular request-oriented workloads, see the description of option .TP .BR --no-host-hdr Specifies that the "Host:" header should not be included when issuing an HTTP request. .TP .BR --num-calls . For session-oriented workloads, see the description of option .BR --wsess . .TP .BI --client= I / N Specifies that the machine .B httperf is running on is client .I I out of a total of .I N clients. .I I should be in the range from 0 to .IR N "-1." Some of the workload generators (e.g., .BR --wset) use the client identity as a bias value to ensure that not all clients generate perfectly identical workloads. When performing a test that involves several client machines, it is generally a good idea to specify this option. .TP .BI --client-session-offsets Specifies that client I of N starts at I/Nths of the way through the wsessionlog file. NOTE: must also specify --client I/N so this client knows where in the wsessionlog file to start. .TP .BI --close-with-reset Requests that .B httperf closes TCP connections by sending a RESET instead of going through the normal TCP connection shutdown handshake. Turning on this option can have ill effects such as data corruption, stuck TCP control blocks, or wrong results. For this reason, the option should not be used unless absolutely necessary and even then it should not be used unless its implications are fully understood. .TP .BI -d= N .TP .BI --debug= N Set debug level to .IR N . Larger values of .I N will result in more output. .TP .BI --failure-status= N Specifies that an HTTP response status code of .I N should be treated as a failure (i.e., treated as if the request had timed out, for example). For example, with .RB `` --failure-status=504 '' responses with an HTTP status of ``504 Gateway Time-out'' would be considered failures. Caveat: this option is currently supported for session workloads only (see the .B --wsess and .B --wsesslog options). .TP .B -h .TP .B --help Prints a summary of available options and their parameters. .TP .BI --hog This option requests to use up as many TCP ports as necessary. Without this option, .B httperf is typically limited to using ephemeral ports (in the range from 1024 to 5000). This limited port range can quickly become a bottleneck so it is generally a good idea to specify this option for serious testing. Also, this option must be specified when measuring NT servers since it avoids a TCP incompatibility between NT and UNIX machines. .TP .BI --http-version= S Specifies the version string that should be included in the requests sent to the server. By default, version string ``1.1'' is used. This option can be set to ``1.0'' to force the generation of HTTP/1.0 requests. Setting this option to any value other than ``1.0'' or ``1.1'' may result in undefined behavior. .TP .BI --max-connections= N Specifies that at most .I N connections are opened for each session. This option is meaningful in conjunction with options .B --wsess and .B --wsesslog only. .TP .BI --max-piped-calls= N Specifies that at most .I N pipelined calls are issued on each connection. This option is meaningful in conjunction with options .B --wsess and .B --wsesslog only. .TP .BI --method= S Specifies the method that should be used when issuing an HTTP request. If this option is not specified, the GET method is used. The method .I S can be an arbitrary string but is usually one of GET, HEAD, PUT, POST, etc. .TP .BI --num-calls= N This option is meaningful for request-oriented workloads only. It specifies the total number of calls to issue on each connection before closing it. If .I N is greater than 1, the server must support persistent connections. The default value for this option is 1. If .BR --burst-length is set to .IR B , then the .I N calls are issued in bursts of .I B pipelined calls each. Thus, the total number of such bursts will be .I N/B (per connection). .TP .BI --num-conns= N This option is meaningful for request-oriented workloads only. It specifies the total number of connections to create. On each connection, calls are issued as specified by options .B --num-calls and .BR --burst-length . A test stops as soon as the .I N connections have either completed or failed. A connection is considered to have failed if any activity on the connection fails to make forward progress for more than the time specified by the timeout options .B --timeout and .BR --think-timeout . The default value for this option is 1. .TP .BI --period= [D]T1[,T2] Specifies the time interval between the creation of connections or sessions. Connections are created by default, sessions if option .B --wsess or .B --wsesslog has been specified. This connection/session ``interarrival time'' can alternatively be specified by the .B --rate option, although more flexibility is available with .B --period. The .I D parameter specifies the interarrival time distribution. If omitted or set to .RB `` d '', a deterministic (i.e., fixed) period is used as specified by parameter .IR T1 in units of seconds. If .I D is set to .RB `` e '', an exponential (i.e., Poisson) distribution is used with a mean interarrival time of .IR T1 . Finally, if .I D is set to .RB `` u '', a uniform distribution over the interval .RI [ T1 , T2 ) is used for the interarrival time. In all cases, a period of 0 results in connections or sessions being generated sequentially (a new connection/session is initiated as soon as the previous one completes). The default value for this option is 0. Note that specifying, for example, .B --rate=5 is equivalent to specifying .B --period=d0.2 or .BR --period=0.2 . By specifying .BR --period=u1,3 , the interarrival times will be randomly chosen from the interval between 1 and 3 seconds. The specific sequence of (pseudo-)random interarrival times are identical from one .B httperf run to another as long as the values for the .B --period and .B --client options are identical. .TP .BI --port= N This option specifies the port number .I N on which the web server is listening for HTTP requests. By default, .B httperf uses port number 80. .TP .BR --print-reply [ = [ header | body ]] Requests the printing of the reply headers, body, and summary. The output is directed to standard output. Reply header lines are prefixed by "RH", reply body lines are prefixed by "RB", and the reply-size summary is prefixed by "RS". The prefix is followed by a serial number that uniquely identifies the call that the reply line is for and a colon (":") character that marks the beginning of the actual reply line. To print only reply headers, pass argument .B header to this option. To print only the reply body, pass argument .B body to this option. .TP .BR --print-request [ = [ header | body ]] Requests the printing of the request headers, body (if one is present), and summary. The output is directed to standard output. Request header lines are prefixed by "SH", request body lines are prefixed by "SB", and the request summary is prefixed by "SS". The prefix is followed by the call's serial number and a colon (":") character that marks the beginning of the actual reply line. To print only request headers, pass argument .B header to this option. To print only the request body, pass argument .B body to this option. .TP .BI --rate= X Specifies the fixed rate at which connections or sessions are created. Connections are created by default, sessions if option .B --wsess or .B --wsesslog has been specified. In both cases a rate of 0 results in connections or sessions being generated sequentially (a new session/connection is initiated as soon as the previous one completes). The default value for this option is 0. .TP .BI --recv-buffer= N Specifies the maximum size of the socket receive buffers used to receive HTTP replies. By default, the limit is 16KB. A smaller value may help memory-constrained clients whereas a larger value may be necessary when communicating with a server over a high-bandwidth, high-latency connection. .TP .BI --retry-on-failure This option is meaningful for session workloads only (see the .B --wsess and .B --wsesslog options). If specified, a call that results in a failure response (as defined by the .B --failure-status option) is retried immediately instead of causing the session to fail. .TP .BI --send-buffer= N Specifies the maximum size of the socket send buffers used to send HTTP requests. By default, the limit is 4KB. A smaller value may help memory-constrained clients whereas a larger value may be necessary when generating large requests to a server connected via a high-bandwidth, high-latency connection. .TP .BI --server= S Specifies the IP hostname of the server. By default, the hostname ``localhost'' is used. This option should always be specified as it is generally not a good idea to run the client and the server on the same machine. .TP .BI --server-name= S Specifies the (default) server name that appears in the "Host:" header of every request sent by .BR httperf . Without this option, the host name (or IP address) specified by option .B --server is used instead. .TP .B --session-cookie When this option is turned on, cookie managment is enabled on a per-session basis. What this means is that if a reply to a request that was generated by session .IR X contains a cookie, then all future requests sent by session .I X will include this cookie as well. At present, the cookie manager in .B httperf supports only one cookie per session. If a second cookie is received, the new cookie overwrites the existing one and a warning message is printed if ``--debug 1'' is on. .TP .B --ssl Specifies that all communication between .B httperf and the server should utilize the Secure Sockets Layer (SSL) protocol. This option is available only if .B httperf was compiled with SSL support enabled. .TP .BI --ssl-ciphers= L This option is only meaningful if SSL is in use (see .B --ssl option). This option specifies the list .I L of cipher suites that .B httperf may use in negotiating a secure connection with the server. If the list contains more than one cipher suite, the ciphers must be separated by a colon. If the server does not accept any of the listed cipher suites, the connection establishment will fail and .B httperf will exit immediately. If this option is not specified when the .B --ssl option is present then .B httperf will use all of the SSLv3 cipher suites provided by the underlying SSL library. .TP .B --ssl-no-reuse This option is only meaningful if SSL and sessions are in use (see .BR --ssl , .BR --wsess , .BR --wsesslog ). When an SSL connection is established the client receives a session identifier (session id) from the server. On subsequent SSL connections, the client normally reuses this session id in order to avoid the expense of repeating the (slow) SSL handshake to establish a new SSL session and obtain another session id (even if the client attempts to re-use a session id, the server may force the client to renegotiate a session). By default .B httperf reuses the session id across all connections in a session. If the .B --ssl-no-reuse option is in effect, then .B httperf will not reuse the session id, and the entire SSL handshake will be performed for each new connection in a session. .TP .B --stagger-start This option causes .B httperf to delay a short period of time before starting to issue requests. This option divides the session period by the number of .B httperf clients; then each client delays for a different fraction of the session period, based on id, so that no two clients start at the same time. .TP .BI --think-timeout= X Specifies the maximum time that the server may need to initiate sending the reply for a given request. Note that this timeout value is added to the normal timeout value (see option .BR --timeout ). When accessing static web content, it is usually not necessary to specify this option. However, when performing tests with long-running CGI scripts, it may be necessary to use this option to allow for larger response-times. The default value for this option is zero seconds, meaning that the server has to be able to respond within the normal timeout value. .TP .BI --timeout= X Specifies the amount of time .I X that .B httperf is willing to wait for a server reaction. The timeout is specified in seconds and can be a fractional number (e.g., .BR "--timeout 3.5" ). This timeout value is used when establishing a TCP connection, when sending a request, when waiting for a reply, and when receiving a reply. If during any of those activities a request fails to make forward progress within the alloted time, .B httperf considers the request to have died, closes the associated connection or session and increases the .B client-timo error count. The actual timeout value used when waiting for a reply is the sum of this timeout and the think-timeout (see option .BR --think-timeout ). By default, the timeout value is infinity. .TP .BI --uri= S Specifies that URI .I S should be accessed on the server. For some of the workload generators (e.g., .BR --wset ), this option specifies the prefix for the URIs being accessed. .TP .B -v .TP .B --verbose Puts .B httperf into verbose mode. In this mode, additional output such as the individual reply rate samples and connection lifetime histogram are printed. .TP .B -V .TP .B --version Prints the version of .BR httperf . .TP .BI --wlog= B , F This option can be used to generate a specific sequence of URI accesses. This is useful to replay the accesses recorded in a server log file, for example. Parameter .I F is the name of a file containing the ASCII NUL separated list of URIs that should be accessed. If parameter .I B is set to .RB `` y '', .B httperf will wrap around to the beginning of the file when reaching the end of the list (so the list of URIs is accessed repeatedly). With .I B set to .RB `` n '', the test will stop no later than when reaching the end of the URI list. .TP .BI --wsess= N1 , N2 , X Requests the generation and measurement of sessions instead of individual requests. A session consists of a sequence of bursts which are spaced out by the user think-time. Each burst consists of a fixed number .I L of calls to the server .RI ( L is specified by option .BR --burst-length ). The calls in a burst are issued as follows: at first, a single call is issued. Once the reply to this first call has been fully received, all remaining calls in the burst are issued concurrently. The concurrent calls are issued either as pipelined calls on an existing persistent connection or as individual calls on separate connections. Whether a persistent connection is used depends on whether the server responds to the first call with a reply that includes a ``Connection: close'' header line. If such a line is present, separate connections are used. The option specifies the following parameters: .I N1 is the total number of sessions to generate, .I N2 is the number of calls per session, and .I X is the user think-time (in seconds) that separates consecutive call bursts. For example, the options .RB `` "--wsess=100,50,10 --burst-len 5" '' would result in 100 sessions with a total of 50 calls each. Since each burst has a length of 5 calls, a total of 10 call bursts would be generated per session. The user think-time between call bursts would be 10 seconds. Note that user think-time .I X denotes the time between receiving the last reply of the previous call burst and the sending of the first request of the next burst. A test involving sessions finishes as soon as the requested number .I N1 of sessions have either failed or completed. A session is considered to have failed if any operation in a session takes longer than the timeouts specified by options .B --timeout and .BR --think-timeout . In addition, a session also fails if the server returns a reply with a status code matching the one specified by option .BR --failure-status . .TP .BI --wsesslog= N , X , F This specifies a session workload generator similar to .B --wsess (please read that description first). With .B --wsesslog though, many aspects of user sessions, including the number and sequence of URI's, request method, think-time and burst-length parameters, can be specified in an input file .I F. Two other parameters are retained from .B --wsess, namely .I N, the number of sessions to initiate, and .I X, the burst-to-burst user think time (note that this becomes a default time since the input file .I F can also specify user think time on a per-burst basis. A small example input file can most-easily show the settable parameters: .br .br # Comment lines start with a ``#'' as the first .br # character. Lines with only whitespace delimit .br # sessions (multiple blank lines do not generate .br # ``null'' sessions). All other lines specify a .br # uri-sequence (1 uri per line). If the first .br # character of the line is whitespace (e.g. space .br # or tab), the uri is considered to be part of a .br # burst that is sent out after the previous .br # non-burst uri. .br .br # session 1 definition (this is a comment) .br /foo.html think=2.0 .br /pict1.gif .br /pict2.gif .br /foo2.html method=POST contents='Post data' .br /pict3.gif headers='If-Modified-Since: Wed Nov 9 12:12:12 2011\n' .br /pict4.gif .br .br # session 2 definition .br /foo3.html method=POST contents="Multiline\\ndata" .br /foo4.html method=HEAD .br .br The above description specifies 2 sessions. The first session will start with a request for /foo.html. When the /foo.html response comes back, a burst of 2 requests will follow (/pict1.gif and /pict2.gif). When the last of those responses is received, a two second user think time is inserted before the next request of /foo2.html is issued. This request is sent as a POST. The posted data can be contained between single- or double-quotes. Newlines can appear within posted data as ``\\n'' or as a ``\\''. The /foo2.html response is followed by a burst request of /pict3.gif and /pict4.gif, which concludes this session. The first request of the second burst, pict3.gif, has a header. Headers can be added to individual requests if httperf is compiled with #ifdef UW_WSESSLOG_HEADERS being true. Each individual request can have multiple headers, with individual headers separated by a newline character (\n). The second session is started some time after the first, as specified by the .B --rate or .B --period options. .br .br The second session consists of 2 requests separated by the default user think time as specified by the .I X parameter of the .B --wsesslog option. If the .I N parameter of .B --wsesslog is greater than the number of sessions defined in input file .IR F , then the defined sessions are used repeatedly until .I N sessions have been created (i.e., the defined sessions are used in a round-robin fashion). .br .br One should avoid using .B --wsesslog in conjunction with other .B httperf options that also control session behavior and workload URI's, namely .B --burst-length, .B --wsess, .B --wlog, and .B --wset. .TP .BI --wset= N , X This option can be used to walk through a list of URIs at a given rate. Parameter .I N specifies the number of distinct URIs that should be generated and .I X specifies the rate at which new URIs are accessed. A rate of .B 0.25 would mean that the same URI would be accessed four times in a row before moving on to the next URI. This type of access pattern is useful in generating a workload that induces a relatively predictable amount of traffic in the disk I/O subsystem of the server (assuming .I N and the accessed files are big enough to exceed the server's buffer cache). The URIs generated are of the form .IR prefix / path .html, where .I prefix is the URI prefix specified by option .B --wset and .I path is generated as follows: for the .IR i -th file in the working set, write down .I i in decimal, prefixing the number with as many zeroes as necessary to get a string that has as many digits as .IR N -1. Then insert a slash character between each digit. For example, the 103rd file in a working set consisting of 1024 files would result in a path of .RB `` 0/1/0/3 ''. Thus, if the URI-prefix is .BR /wset1024 , then the URI being accessed would be .BR /wset1024/0/1/0/3.html . In other words, the files on the server need to be organized as a 10ary tree. .SH OUTPUT This section describes the statistics output at the end of each test run. The basic information shown below is printed independent of the selected workload generator. .PP .RS .br .B Total: connections 30000 requests 29997 replies 29997 test-duration 299.992 s .PP .B Connection rate: 100.0 conn/s (10.0 ms/conn, <=14 concurrent connections) .br .B Connection time [ms]: min 1.4 avg 3.0 max 163.4 median 1.5 stddev 7.3 .br .B Connection time [ms]: connect 0.6 .br .B Connection length [replies/conn]: 1.000 .PP .B Request rate: 100.0 req/s (10.0 ms/req) .br .B Request size [B]: 75.0 .PP .B Reply rate [replies/s]: min 98.8 avg 100.0 max 101.2 stddev 0.3 (60 samples) .br .B Reply time [ms]: response 2.4 transfer 0.0 .br .B Reply size [B]: header 242.0 content 1010.0 footer 0.0 (total 1252.0) .br .B Reply status: 1xx=0 2xx=29997 3xx=0 4xx=0 5xx=0 .PP .B CPU time [s]: user 94.31 system 205.26 (user 31.4% system 68.4% total 99.9%) .br .B Net I/O: 129.6 KB/s (1.1*10^6 bps) .PP .B Errors: total 3 client-timo 0 socket-timo 0 connrefused 3 connreset 0 .br .B Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0 .br .RE .PP There are six groups of statistics: overall results (``Total''), connection related results (``Connection''), results relating to the issuing of HTTP requests (``Request''), results relating to the replies received from the server (``Reply''), miscellaneous results relating to the CPU (``CPU'') and network (``Net I/O'') utilization and, last but not least, a summary of errors encountered (``Errors''). .TP Total Section .br This section summarizes how many TCP connections were initiated by .BR httperf , how many requests it sent out, how many replies it received, and what the total test duration was. In the example output shown above, 30,000 connections were created, 29,997 requests were sent out and 29,997 replies were received. The duration of the test was almost exactly 5 minutes (300 seconds). .TP Connection Section .br This section conveys information related to TCP connections generated by the tool. Specifically, the ``Connection rate'' line shows that new connections were initiated at a rate of 100.0 connections per second. This rate corresponds to a period of 10.0 milliseconds per connection. The last number in this line shows that at most 14 connections were open at any given time. The first line labeled ``Connection time'' gives lifetime statistics for successful connections. The lifetime of a connection is the time between a TCP connection is initiated and the time the connection is closed. A connection is considered successful if it had at least one call that completed successfully. In the example output, the line indicates that the minimum (``min'') connection lifetime was 1.4 milliseconds, the average (``avg'') lifetime was 3.0 milliseconds, the maximum (``max'') was 163.4 milliseconds, the median (``median'') lifetime was 1.5 milliseconds, and that the standard deviation of the lifetimes was 7.3 milliseconds. The median lifetime is computed based on a histogram with one millisecond resolution and a maximum lifetime of 100 seconds. Thus, the median is accurate to within half a millisecond if at least half of the successful connections have a lifetime of no more than 100 seconds. The next statistic in this section is the average time it took to establish a TCP connection. Only successful TCP connection establishments are counted. In the example, the second line labeled ``Connection time'' shows that, on average, it took 0.6 milliseconds to establish a connection. The final line in this section is labeled ``Connection length.'' It gives the average number of replies received on each connection that received at least one reply (i.e., connections that failed before yielding the first reply are not counted). This number can be bigger than 1.0 due to persistent connections. .TP Request Section .br The line labeled ``Request rate'' gives the rate at which HTTP requests were issued and the period that this rate corresponds to. In the example above, the request rate was 100.0 requests per second, which corresponds to 10.0 milliseconds per request. As long as no persistent connections are employed, the results in this section are very similar or identical to results in the connection section. However, when persistent connections are used, several calls can be performed on a single connection in which case the results would be different. The line labeled ``Request size'' gives the average size of the HTTP requests in bytes. In the example above, the average request size was 75 bytes. .TP Reply Section .br For simple measurements, this section is often the most interesting one as the line labeled ``Reply rate'' gives various statistics for the reply rate. In the example above, the minimum (``min'') reply rate was 98.8 replies per second, the average (``avg'') was 100 replies per second, and the maximum (``max'') rate was 101.2 replies per second. The standard deviation was 0.3 replies per second. The number enclosed in parentheses shows that 60 reply rate samples were acquired. At present, .B httperf collects a rate sample once every five seconds. To obtain a meaningful standard deviation, it is recommended to run tests long enough so at least thirty samples are obtained. This corresponds to a test duration of at least 150 seconds. The line labeled ``Reply Time'' gives information on how long it took for the server to respond and how long it took to receive the reply. In the example, it took on average 2.4 milliseconds between sending the first byte of the request and receiving the first byte of the reply. The time to ``transfer'', or read, the reply was too short to be measured, so it shows up as zero. The is typical when the entire reply fits into a single TCP segment. The next line, labeled ``Reply size'' contains statistics on the average size of the replies---all numbers are in reported bytes. Specifically, the line lists the average length of reply headers, the content, and footers (HTTP/1.1 uses footers to realize the ``chunked'' transfer encoding). For convenience, the average total number of bytes in the replies is also given in parentheses. In the example, the average header length (``header'') was 242 bytes, the average content length (``content'') was 1010 bytes, and there were no footers (``footer'' length is zero). The total reply length of 1252 bytes on average. The final line in this section is a histogram of the major status codes received in the replies from the server. The major status code is the ``hundreds''-digit of the full HTTP status code. In the example, all 29,997 replies had a major status code of 2. It's a good guess that all status codes were ``200 OK'' but the information in the histogram is not detailed enough to allow distinguishing status codes with the same major code. .TP Miscellaneous Section .br This section starts with a summary of the CPU utilization on the client machine. In the example, the line labeled ``CPU time'' shows that 94.31 seconds were spent executing in user mode (``user''), 205.26 seconds were spent executing in system mode (``system'') and that this corresponds to 31.4% user mode execution and 68.4% system execution. The total utilization was 99.9%, which is expected given that .B httperf is a CPU hog. A total CPU utilization of significantly less than 100% is a sign that there were competing processes that interfered with the test. The line labeled ``Net I/O'' gives the average network throughput in kilobytes per second (where a kilobyte is 1024 bytes) and in megabits per second (where a megabit is 10^6 bits). In the example, an average network usage of about 129.6 kilobytes per second was sustained. The number in parentheses shows that this corresponds to about 1.1 megabits per second. This network bandwidth is computed based on the number of bytes sent and received on the TCP connections. In other words, it does not account for the network headers or TCP retransmissions that may have occurred. .TP Errors Section .br The last section contains statistics on the errors that were encountered during a test. In the example, the two lines labeled ``Errors'' show that there were a total of three errors and that all three errors were due to the server refusing to accept a connection (``connrefused''). A description of each error counter follows: .B client-timo: The number of times a session, connection, or call failed due to a client timeout (as specified by the .B --timeout and .BR --think-timeout ) options. .B socket-timo: The number of times a TCP connection failed with a socket-level timeout (ETIMEDOUT). .B connrefused: The number of times a TCP connection attempt failed with a ``connection refused by server'' error (ECONNREFUSED). .B connreset: The number of times a TCP connection failed due to a RESET from the server. Typically, a RESET is received when the client attempts to send data to the server at a time the server has already closed its end of the connection. NT servers also send RESETs when attempting to establish a new connection when the listen queue is full. .B fd-unavail: The number of times the .B httperf process was out of file descriptors. Whenever this count is non-zero, the test results are meaningless because the client was overloaded (see section "CHOOSING TIMEOUT VALUES"). .B addrunavail: The number of times the client was out of TCP port numbers (EADDRNOTAVAIL). This error should never occur. If it does, the results should be discarded. .B ftab-full: The number of times the system's file descriptor table is full. Again, this error should never occur. If it does, the results should be discarded. .B other: The number of times some other type of error occurred. Whenever this counter is non-zero, it is necessary to track down the real cause of the error. To assist in doing this, .B httperf prints the error code (errno) of the first unknown errors that occurs during a test run. .RE .PP When .B --wsess or .B --wsesslog is specified, .B httperf generates and measures sessions instead of individual calls and additional statistics are printed at the end of a test. An example output is shown below. .PP .RS .B Session rate [sess/s]: min 0.00 avg 0.59 max 2.40 stddev 0.37 (240/450) .br .B Session: avg 6.45 connections/session .br .B Session lifetime [s]: 123.9 .br .B Session failtime [s]: 58.5 .br .B Session length histogram: 4 7 4 ... 3 3 240 .RE .PP The line labeled ``Session rate'' shows the minium, average, and maximum rate at which sessions completed (based on a 5 second sampling interval). It also shows the standard deviation of the session completion rate. The numbers in parentheses show how many sessions succeeded and how many sessions were initiated. In the example above, the minimum, average, and maximum session completion rates were 0.00, 0.59, and 2.40 sessions per second, respectively. The standard deviation was 0.37 sessions per second and 240 out of 450 sessions completed successfully (210 failed due to errors such as timeouts). The next line, labeled ``Session:'' shows the average length of a session measured in connections. In the example above, an average of 6.45 connections were required to complete a session. The line labeled ``Session lifetime'' gives the average time it took to complete a successful session. In the example above, it took an average of 123.9 seconds. The line labeled ``Session failtime'' gives the average time it took before an unsuccessful session failed. In the example above, it took on average 58.5 seconds for a session to fail. Finally, the line labeled ``Session length histogram'' gives a histogram of the number of replies received by each session. In the example above, 4 sessions ended after receiving no reply at all, 7 ended after receiving one reply, and so on (the ellipsis indicates additional histogram counts that were omitted from this manual for space reasons). Note that this histogram does not distinguish between successful and failed sessions. .SH CHOOSING TIMEOUT VALUES Since the machine that .B httperf runs on has only a finite set of resource available, it can not sustain arbitrarily high HTTP loads. For example, one limiting factor is that there are only roughly 60,000 TCP port numbers that can be in use at any given time. Since on most UNIX systems it takes one minute for a TCP connection to be fully closed (leave the TIME_WAIT state), the maximum rate a client can sustain is at most 1,000 requests per second. The actual sustainable rate is often much lower than that because before running out of TCP ports, the machine is likely to run out of file descriptors (one file descriptor is used up for each open TCP connection). By default, HP-UX 10.20 allows 1,024 open file descriptors per process. This means that without extra precautions, .B httperf could potentially very quickly use up all available file descriptors, at which point it could not induce any additional load on the server. To avoid this problem, .B httperf provides option .B --timeout to set a timeout for all communication with the server. If the server does not respond before the timeout expires, the client considers the corresponding session, connection, or call to be ``dead,'' closes the associated TCP connection, and increases the ``client-timo'' error count. The only exception to this rule is that after sending an entire request to the server, .B httperf allows the server to take some additional time before it starts sending the reply. This is to accommodate HTTP requests that take a long time to complete on the server. This additional time is called the ``server think time'' and can be specified by option .BR --think-timeout . By default, this additional think time is zero seconds, so the server would always have to respond within the time alloted by option .BR --timeout . Timeouts allow .B httperf to sustain high offered loads even when the server is overloaded. For example, with a timeout of 2 seconds and assuming that 1,000 file-descriptors are available, the offered load could be up to 500 requests per second (in practice, the sustainable load is often somewhat smaller than the theoretical value). On the downside, timeouts artificially truncate the connection lifetime distribution. Thus, it is recommended to pick a timeout value that is as large as possible yet small enough to allow sustaining the desired offered rate. A timeout as short as one second may be acceptable, but larger timeouts (5-10 seconds) are preferable. It is important to keep in mind that timeouts do not guarantee that a client can sustain a particular offered load---there are many other potential resource bottlenecks. For example, in some cases the client machine may simply run out of CPU time. To ensure that a given test really measured the server's capabilities and not the client's, it is a good idea to vary the number of machines participating in a test. If observed performance remains the same as the number of client machines is varied, the test results are likely to be valid. .SH AUTHOR .BR httperf was developed by David Mosberger and was heavily influenced by an earlier tool written by Tai Jin. Stephane Eranian contributed the log-file based URI generator. Dick Carter contributed the .B --wsesslog workload generator, the support behind the .B --period option, and bug fixes. All four authors are with Hewlett-Packard Research Laboratories. .SH BUGS Probably many. Always be sure to double-check results and don't fall prey to measuring client-performance instead of server performance! .PP The user-interface definitely could be improved. A simple workload description language might be more suitable than the dozens of little command-line options the tool has right now. ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/idleconn.c ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include const char *prog_name; unsigned long num_conn, num_closed; struct timeval start_time; void sigint_handler (int signal) { struct timeval stop_time; double delta_t; gettimeofday (&stop_time, NULL); delta_t = ((stop_time.tv_sec - start_time.tv_sec) + 1e-6*(stop_time.tv_usec - start_time.tv_usec)); printf ("%s: total # conn. created = %lu, close() rate = %g conn/sec\n", prog_name, num_conn, num_closed / delta_t); exit (0); } int main (int argc, char **argv) { int desired, current = 0, port, sd, max_sd = 0, n, i; struct sockaddr_in sin, server_addr; fd_set readable, rdfds; struct rlimit rlimit; struct hostent *he; char *server; signal (SIGINT, sigint_handler); prog_name = strrchr (argv[0], '/'); if (prog_name) ++prog_name; else prog_name = argv[0]; memset (&rdfds, 0, sizeof (rdfds)); if (argc != 4) { fprintf (stderr, "Usage: %s server port numidle\n", prog_name); exit (-1); } server = argv[1]; port = atoi (argv[2]); desired = atoi (argv[3]); /* boost open file limit to the max: */ if (getrlimit (RLIMIT_NOFILE, &rlimit) < 0) { fprintf (stderr, "%s: failed to get number of open file limit: %s", prog_name, strerror (errno)); exit (1); } if (rlimit.rlim_max > FD_SETSIZE) { fprintf (stderr, "%s: warning: open file limit = %ld > FD_SETSIZE\n" " limiting max. # of open files to FD_SETSIZE = %ld\n", prog_name, (long int) rlimit.rlim_max, (long int) FD_SETSIZE); rlimit.rlim_max = FD_SETSIZE; } rlimit.rlim_cur = rlimit.rlim_max; if (setrlimit (RLIMIT_NOFILE, &rlimit) < 0) { fprintf (stderr, "%s: failed to increase number of open file limit: %s", prog_name, strerror (errno)); exit (1); } printf ("%s: creating and maintaining %d idle connections\n", prog_name, desired); memset (&server_addr, 0, sizeof (server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons (port); he = gethostbyname (server); if (he) { if (he->h_addrtype != AF_INET || he->h_length != sizeof (sin.sin_addr)) { perror (server); exit (-1); } memcpy (&server_addr.sin_addr, he->h_addr_list[0], sizeof (server_addr.sin_addr)); } else if (!inet_aton (server, &server_addr.sin_addr)) { fprintf (stderr, "%s: invalid server address %s\n", prog_name, server); exit (-1); } gettimeofday (&start_time, NULL); while (1) { while (current < desired) { /* create more idle connections */ sd = socket (AF_INET, SOCK_STREAM, 0); if (sd < 0) { perror ("socket"); exit (-1); } sin = server_addr; if (connect (sd, (struct sockaddr *) &sin, sizeof (sin)) < 0) { printf("connect: %s\n", strerror (errno)); switch (errno) { case ECONNREFUSED: /* wait for server to start up... */ usleep (1000000); case ETIMEDOUT: close (sd); continue; default: perror ("connect"); exit (-1); } } if (sd > max_sd) max_sd = sd; #if DEBUG > 1 printf ("created %d\n", sd); #endif ++num_conn; ++current; FD_SET(sd, &rdfds); } readable = rdfds; n = select (max_sd + 1, &readable, NULL, NULL, NULL); for (i = 0; i <= max_sd; ++i) { if (FD_ISSET (i, &readable)) { #if DEBUG > 1 printf ("closed %d\n", i); #endif close (i); --current; --n; ++num_closed; FD_CLR(i, &rdfds); } if (n <= 0) break; } } } ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/install-sh ================================================ #!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: chmodcmd="" else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/lib/COPYING.txt ================================================ FILE QUARANTINED Microsoft Forefront Protection for Exchange Server (edge1) removed a file since it was found to match a filter. File name: "httperf-new.tgz->->httperf/lib/COPYING.LIB" Filter name: "FILE FILTER= SBCS extension filtering: *.lib*" ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/lib/Makefile ================================================ # Generated automatically from Makefile.in by configure. SHELL=/bin/sh top_srcdir = .. top_builddir = .. prefix = /usr/local bindir = ${exec_prefix}/bin mandir = ${prefix}/man CC = gcc RANLIB = ranlib INCLUDES = -I$(top_builddir) -I$(top_srcdir) -I$(top_srcdir)/lib \ $(SSL_INCLUDES) -I/usr/kerberos/include DEFS = -DHAVE_CONFIG_H CPPFLAGS = -DNDEBUG -D_GNU_SOURCE -D_XOPEN_SOURCE CFLAGS = -g -O2 -Wall LDFLAGS = LIBS = -lssl -lcrypto -lm CPPFLAGS += -DBIG_FD_SETSIZE COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -static -static-libgcc LINK = $(CC) $(LDFLAGS) -static -static-libgcc -o $@ .c.o: $(COMPILE) $< LIBUTIL_OBJS = getopt.o getopt1.o ssl_writev.o all: libutil.a libutil.a: $(LIBUTIL_OBJS) ar r $@ $(LIBUTIL_OBJS) $(RANLIB) $@ depend: install: clean: rm -f libutil.a $(LIBUTIL_OBJS) distclean: clean rm -f *~ .PHONY: all install clean distclean depend ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/lib/Makefile.in ================================================ SHELL=/bin/sh VPATH = @srcdir@ top_srcdir = @top_srcdir@ top_builddir = .. prefix = @prefix@ bindir = @bindir@ mandir = @mandir@ CC = @CC@ RANLIB = @RANLIB@ INCLUDES = -I$(top_builddir) -I$(top_srcdir) -I$(top_srcdir)/lib \ $(SSL_INCLUDES) -I/usr/kerberos/include DEFS = @DEFS@ CPPFLAGS = @CPPFLAGS@ CFLAGS = @CFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ CPPFLAGS += -DBIG_FD_SETSIZE COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -static -static-libgcc LINK = $(CC) $(LDFLAGS) -static -static-libgcc -o $@ @SET_MAKE@ .c.o: $(COMPILE) $< LIBUTIL_OBJS = getopt.o getopt1.o ssl_writev.o all: libutil.a libutil.a: $(LIBUTIL_OBJS) ar r $@ $(LIBUTIL_OBJS) $(RANLIB) $@ depend: install: clean: rm -f libutil.a $(LIBUTIL_OBJS) distclean: clean rm -f *~ .PHONY: all install clean distclean depend ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/lib/README ================================================ This directory contains library-replacement functions that are needed on some platforms. This code is copyright by the Free Software Foundation and a copy of the license under which it is distributed can be found in the file COPYING.LIB in this directory. ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/lib/getopt.c ================================================ /* Getopt for GNU. NOTE: getopt is now part of the C library, so if you don't know what "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu before changing it! Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. This file is part of the GNU C Library. Its master source is NOT part of the C library, however. The master source lives in /gd/gnu/lib. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* This tells Alpha OSF/1 not to define a getopt prototype in . Ditto for AIX 3.2 and . */ #ifndef _NO_PROTO #define _NO_PROTO #endif #include "config.h" #ifndef HAVE_GETOPT_LONG #include #include #if !defined (__STDC__) || !__STDC__ /* This is a separate conditional since some stdc systems reject `defined (const)'. */ #ifndef const #define const #endif #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #if defined (_LIBC) || !defined (__GNU_LIBRARY__) /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ /* Don't include stdlib.h for non-GNU C libraries because some of them contain conflicting prototypes for getopt. */ #include #include #endif /* GNU C library. */ #ifdef VMS #include #if HAVE_STRING_H - 0 #include #endif #endif #if defined (WIN32) && !defined (__CYGWIN32__) /* It's not Unix, really. See? Capital letters. */ #include #define getpid() GetCurrentProcessId() #endif #ifndef _ /* This is for other GNU distributions with internationalized messages. When compiling libc, the _ macro is predefined. */ #if defined(HAVE_LIBINTL_H) && defined(ENABLE_NLS) # include # define _(msgid) gettext (msgid) #else # define _(msgid) (msgid) #endif #endif /* This version of `getopt' appears to the caller like standard Unix `getopt' but it behaves differently for the user, since it allows the user to intersperse the options with the other arguments. As `getopt' works, it permutes the elements of ARGV so that, when it is done, all the options precede everything else. Thus all application programs are extended to handle flexible argument order. Setting the environment variable POSIXLY_CORRECT disables permutation. Then the behavior is completely standard. GNU application programs can use a third alternative mode in which they can distinguish the relative order of options and other arguments. */ #include "getopt.h" /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ char *optarg = NULL; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns EOF, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ /* XXX 1003.2 says this must be 1 before any call. */ int optind = 0; /* The next char to be scanned in the option-element in which the last option character we returned was found. This allows us to pick up the scan where we left off. If this is zero, or a null string, it means resume the scan by advancing to the next ARGV-element. */ static char *nextchar; /* Callers store zero here to inhibit the error message for unrecognized options. */ int opterr = 1; /* Set to an option character which was unrecognized. This must be initialized on some systems to avoid linking in the system's own getopt implementation. */ int optopt = '?'; /* Describe how to deal with options that follow non-option ARGV-elements. If the caller did not specify anything, the default is REQUIRE_ORDER if the environment variable POSIXLY_CORRECT is defined, PERMUTE otherwise. REQUIRE_ORDER means don't recognize them as options; stop option processing when the first non-option is seen. This is what Unix does. This mode of operation is selected by either setting the environment variable POSIXLY_CORRECT, or using `+' as the first character of the list of option characters. PERMUTE is the default. We permute the contents of ARGV as we scan, so that eventually all the non-options are at the end. This allows options to be given in any order, even with programs that were not written to expect this. RETURN_IN_ORDER is an option available to programs that were written to expect options and other ARGV-elements in any order and that care about the ordering of the two. We describe each non-option ARGV-element as if it were the argument of an option with character code 1. Using `-' as the first character of the list of option characters selects this mode of operation. The special argument `--' forces an end of option-scanning regardless of the value of `ordering'. In the case of RETURN_IN_ORDER, only `--' can cause `getopt' to return EOF with `optind' != ARGC. */ static enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering; /* Value of POSIXLY_CORRECT environment variable. */ static char *posixly_correct; #ifdef __GNU_LIBRARY__ /* We want to avoid inclusion of string.h with non-GNU libraries because there are many ways it can cause trouble. On some systems, it contains special magic macros that don't work in GCC. */ #include #define my_index strchr #else /* Avoid depending on library functions or files whose names are inconsistent. */ char *getenv (); static char * my_index (str, chr) const char *str; int chr; { while (*str) { if (*str == chr) return (char *) str; str++; } return 0; } /* If using GCC, we can safely declare strlen this way. If not using GCC, it is ok not to declare it. */ #ifdef __GNUC__ /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. That was relevant to code that was here before. */ #if !defined (__STDC__) || !__STDC__ /* gcc with -traditional declares the built-in strlen to return int, and has done so at least since version 2.4.5. -- rms. */ extern int strlen (const char *); #endif /* not __STDC__ */ #endif /* __GNUC__ */ #endif /* not __GNU_LIBRARY__ */ /* Handle permutation of arguments. */ /* Describe the part of ARGV that contains non-options that have been skipped. `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is the index after the last of them. */ static int first_nonopt; static int last_nonopt; /* Bash 2.0 gives us an environment variable containing flags indicating ARGV elements that should not be considered arguments. */ static const char *nonoption_flags; static int nonoption_flags_len; /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) which contains all the non-options that have been skipped so far. The other is elements [last_nonopt,optind), which contains all the options processed since those non-options were skipped. `first_nonopt' and `last_nonopt' are relocated so that they describe the new indices of the non-options in ARGV after they are moved. */ #if defined (__STDC__) && __STDC__ static void exchange (char **); #endif static void exchange (argv) char **argv; { int bottom = first_nonopt; int middle = last_nonopt; int top = optind; char *tem; /* Exchange the shorter segment with the far end of the longer segment. That puts the shorter segment into the right place. It leaves the longer segment in the right place overall, but it consists of two parts that need to be swapped next. */ while (top > middle && middle > bottom) { if (top - middle > middle - bottom) { /* Bottom segment is the short one. */ int len = middle - bottom; register int i; /* Swap it with the top part of the top segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[top - (middle - bottom) + i]; argv[top - (middle - bottom) + i] = tem; } /* Exclude the moved bottom segment from further swapping. */ top -= len; } else { /* Top segment is the short one. */ int len = top - middle; register int i; /* Swap it with the bottom part of the bottom segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[middle + i]; argv[middle + i] = tem; } /* Exclude the moved top segment from further swapping. */ bottom += len; } } /* Update records for the slots the non-options now occupy. */ first_nonopt += (optind - last_nonopt); last_nonopt = optind; } /* Initialize the internal data when the first call is made. */ #if defined (__STDC__) && __STDC__ static const char *_getopt_initialize (const char *); #endif static const char * _getopt_initialize (optstring) const char *optstring; { /* Start processing options with ARGV-element 1 (since ARGV-element 0 is the program name); the sequence of previously skipped non-option ARGV-elements is empty. */ first_nonopt = last_nonopt = optind = 1; nextchar = NULL; posixly_correct = getenv ("POSIXLY_CORRECT"); /* Determine how to handle the ordering of options and nonoptions. */ if (optstring[0] == '-') { ordering = RETURN_IN_ORDER; ++optstring; } else if (optstring[0] == '+') { ordering = REQUIRE_ORDER; ++optstring; } else if (posixly_correct != NULL) ordering = REQUIRE_ORDER; else ordering = PERMUTE; if (posixly_correct == NULL) { /* Bash 2.0 puts a special variable in the environment for each command it runs, specifying which ARGV elements are the results of file name wildcard expansion and therefore should not be considered as options. */ char var[100]; sprintf (var, "_%d_GNU_nonoption_argv_flags_", getpid ()); nonoption_flags = getenv (var); if (nonoption_flags == NULL) nonoption_flags_len = 0; else nonoption_flags_len = strlen (nonoption_flags); } return optstring; } /* Scan elements of ARGV (whose length is ARGC) for option characters given in OPTSTRING. If an element of ARGV starts with '-', and is not exactly "-" or "--", then it is an option element. The characters of this element (aside from the initial '-') are option characters. If `getopt' is called repeatedly, it returns successively each of the option characters from each of the option elements. If `getopt' finds another option character, it returns that character, updating `optind' and `nextchar' so that the next call to `getopt' can resume the scan with the following option character or ARGV-element. If there are no more option characters, `getopt' returns `EOF'. Then `optind' is the index in ARGV of the first ARGV-element that is not an option. (The ARGV-elements have been permuted so that those that are not options now come last.) OPTSTRING is a string containing the legitimate option characters. If an option character is seen that is not listed in OPTSTRING, return '?' after printing an error message. If you set `opterr' to zero, the error message is suppressed but we still return '?'. If a char in OPTSTRING is followed by a colon, that means it wants an arg, so the following text in the same ARGV-element, or the text of the following ARGV-element, is returned in `optarg'. Two colons mean an option that wants an optional arg; if there is text in the current ARGV-element, it is returned in `optarg', otherwise `optarg' is set to zero. If OPTSTRING starts with `-' or `+', it requests different methods of handling the non-option ARGV-elements. See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. Long-named options begin with `--' instead of `-'. Their names may be abbreviated as long as the abbreviation is unique or is an exact match for some defined option. If they have an argument, it follows the option name in the same ARGV-element, separated from the option name by a `=', or else the in next ARGV-element. When `getopt' finds a long-named option, it returns 0 if that option's `flag' field is nonzero, the value of the option's `val' field if the `flag' field is zero. The elements of ARGV aren't really const, because we permute them. But we pretend they're const in the prototype to be compatible with other systems. LONGOPTS is a vector of `struct option' terminated by an element containing a name which is zero. LONGIND returns the index in LONGOPT of the long-named option found. It is only valid when a long-named option has been found by the most recent call. If LONG_ONLY is nonzero, '-' as well as '--' can introduce long-named options. */ int _getopt_internal (argc, argv, optstring, longopts, longind, long_only) int argc; char *const *argv; const char *optstring; const struct option *longopts; int *longind; int long_only; { optarg = NULL; if (optind == 0) { optstring = _getopt_initialize (optstring); optind = 1; /* Don't scan ARGV[0], the program name. */ } /* Test whether ARGV[optind] points to a non-option argument. Either it does not have option syntax, or there is an environment flag from the shell indicating it is not an option. */ #define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ || (optind < nonoption_flags_len \ && nonoption_flags[optind] == '1')) if (nextchar == NULL || *nextchar == '\0') { /* Advance to the next ARGV-element. */ /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been moved back by the user (who may also have changed the arguments). */ if (last_nonopt > optind) last_nonopt = optind; if (first_nonopt > optind) first_nonopt = optind; if (ordering == PERMUTE) { /* If we have just processed some options following some non-options, exchange them so that the options come first. */ if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (last_nonopt != optind) first_nonopt = optind; /* Skip any additional non-options and extend the range of non-options previously skipped. */ while (optind < argc && NONOPTION_P) optind++; last_nonopt = optind; } /* The special ARGV-element `--' means premature end of options. Skip it like a null option, then exchange with previous non-options as if it were an option, then skip everything else like a non-option. */ if (optind != argc && !strcmp (argv[optind], "--")) { optind++; if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (first_nonopt == last_nonopt) first_nonopt = optind; last_nonopt = argc; optind = argc; } /* If we have done all the ARGV-elements, stop the scan and back over any non-options that we skipped and permuted. */ if (optind == argc) { /* Set the next-arg-index to point at the non-options that we previously skipped, so the caller will digest them. */ if (first_nonopt != last_nonopt) optind = first_nonopt; return EOF; } /* If we have come to a non-option and did not permute it, either stop the scan or describe it to the caller and pass it by. */ if (NONOPTION_P) { if (ordering == REQUIRE_ORDER) return EOF; optarg = argv[optind++]; return 1; } /* We have found another option-ARGV-element. Skip the initial punctuation. */ nextchar = (argv[optind] + 1 + (longopts != NULL && argv[optind][1] == '-')); } /* Decode the current option-ARGV-element. */ /* Check whether the ARGV-element is a long option. If long_only and the ARGV-element has the form "-f", where f is a valid short option, don't consider it an abbreviated form of a long option that starts with f. Otherwise there would be no way to give the -f short option. On the other hand, if there's a long option "fubar" and the ARGV-element is "-fu", do consider that an abbreviation of the long option, just like "--fu", and not "-f" with arg "u". This distinction seems to be the most useful approach. */ if (longopts != NULL && (argv[optind][1] == '-' || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) { char *nameend; const struct option *p; const struct option *pfound = NULL; int exact = 0; int ambig = 0; int indfound = 0; int option_index; for (nameend = nextchar; *nameend && *nameend != '='; nameend++) /* Do nothing. */ ; /* Test all long options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) if (!strncmp (p->name, nextchar, nameend - nextchar)) { if (nameend - nextchar == strlen (p->name)) { /* Exact match found. */ pfound = p; indfound = option_index; exact = 1; break; } else if (pfound == NULL) { /* First nonexact match found. */ pfound = p; indfound = option_index; } else /* Second or later nonexact match found. */ ambig = 1; } if (ambig && !exact) { if (opterr) fprintf (stderr, _("%s: option `%s' is ambiguous\n"), argv[0], argv[optind]); nextchar += strlen (nextchar); optind++; optopt = 0; return '?'; } if (pfound != NULL) { option_index = indfound; optind++; if (*nameend) { /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */ if (pfound->has_arg) optarg = nameend + 1; else { if (opterr) { if (argv[optind - 1][1] == '-') { /* --option */ fprintf (stderr, _("%s: option `--%s' doesn't allow an argument\n"), argv[0], pfound->name); } else { /* +option or -option */ fprintf (stderr, _("%s: option `%c%s' doesn't allow an argument\n"), argv[0], argv[optind - 1][0], pfound->name); } } nextchar += strlen (nextchar); optopt = pfound->val; return '?'; } } else if (pfound->has_arg == 1) { if (optind < argc) optarg = argv[optind++]; else { if (opterr) fprintf (stderr, _("%s: option `%s' requires an argument\n"), argv[0], argv[optind - 1]); nextchar += strlen (nextchar); optopt = pfound->val; return optstring[0] == ':' ? ':' : '?'; } } nextchar += strlen (nextchar); if (longind != NULL) *longind = option_index; if (pfound->flag) { *(pfound->flag) = pfound->val; return 0; } return pfound->val; } /* Can't find it as a long option. If this is not getopt_long_only, or the option starts with '--' or is not a valid short option, then it's an error. Otherwise interpret it as a short option. */ if (!long_only || argv[optind][1] == '-' || my_index (optstring, *nextchar) == NULL) { if (opterr) { if (argv[optind][1] == '-') /* --option */ fprintf (stderr, _("%s: unrecognized option `--%s'\n"), argv[0], nextchar); else /* +option or -option */ fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), argv[0], argv[optind][0], nextchar); } nextchar = (char *) ""; optind++; optopt = 0; return '?'; } } /* Look at and handle the next short option-character. */ { char c = *nextchar++; char *temp = my_index (optstring, c); /* Increment `optind' when we start to process its last character. */ if (*nextchar == '\0') ++optind; if (temp == NULL || c == ':') { if (opterr) { if (posixly_correct) /* 1003.2 specifies the format of this message. */ fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c); else fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c); } optopt = c; return '?'; } if (temp[1] == ':') { if (temp[2] == ':') { /* This is an option that accepts an argument optionally. */ if (*nextchar != '\0') { optarg = nextchar; optind++; } else optarg = NULL; nextchar = NULL; } else { /* This is an option that requires an argument. */ if (*nextchar != '\0') { optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, we must advance to the next element now. */ optind++; } else if (optind == argc) { if (opterr) { /* 1003.2 specifies the format of this message. */ fprintf (stderr, _("%s: option requires an argument -- %c\n"), argv[0], c); } optopt = c; if (optstring[0] == ':') c = ':'; else c = '?'; } else /* We already incremented `optind' once; increment it again when taking next ARGV-elt as argument. */ optarg = argv[optind++]; nextchar = NULL; } } return c; } } int getopt (argc, argv, optstring) int argc; char *const *argv; const char *optstring; { return _getopt_internal (argc, argv, optstring, (const struct option *) 0, (int *) 0, 0); } #endif /* _LIBC or not __GNU_LIBRARY__. */ #ifdef TEST /* Compile with -DTEST to make an executable for use in testing the above definition of `getopt'. */ int main (argc, argv) int argc; char **argv; { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; c = getopt (argc, argv, "abc:d:0123456789"); if (c == EOF) break; switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); } #endif /* TEST */ #endif /* HAVE_GETOPT_LONG */ ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/lib/getopt.h ================================================ /* Declarations for getopt. Copyright (C) 1989, 90, 91, 92, 93, 94 Free Software Foundation, Inc. This file is part of the GNU C Library. Its master source is NOT part of the C library, however. The master source lives in /gd/gnu/lib. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _GETOPT_H #define _GETOPT_H 1 #ifdef __cplusplus extern "C" { #endif /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ extern char *optarg; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns EOF, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ extern int optind; /* Callers store zero here to inhibit the error message `getopt' prints for unrecognized options. */ extern int opterr; /* Set to an option character which was unrecognized. */ extern int optopt; /* Describe the long-named options requested by the application. The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector of `struct option' terminated by an element containing a name which is zero. The field `has_arg' is: no_argument (or 0) if the option does not take an argument, required_argument (or 1) if the option requires an argument, optional_argument (or 2) if the option takes an optional argument. If the field `flag' is not NULL, it points to a variable that is set to the value given in the field `val' when the option is found, but left unchanged if the option is not found. To have a long-named option do something other than set an `int' to a compiled-in constant, such as set a value from `optarg', set the option's `flag' field to zero and its `val' field to a nonzero value (the equivalent single-letter option character, if there is one). For long options that have a zero `flag' field, `getopt' returns the contents of the `val' field. */ struct option { #if defined (__STDC__) && __STDC__ const char *name; #else char *name; #endif /* has_arg can't be an enum because some compilers complain about type mismatches in all the code that assumes it is an int. */ int has_arg; int *flag; int val; }; /* Names for the values of the `has_arg' field of `struct option'. */ #define no_argument 0 #define required_argument 1 #define optional_argument 2 #if defined (__STDC__) && __STDC__ #ifdef __GNU_LIBRARY__ /* Many other libraries have conflicting prototypes for getopt, with differences in the consts, in stdlib.h. To avoid compilation errors, only prototype getopt for the GNU C library. */ extern int getopt (int argc, char *const *argv, const char *shortopts); #else /* not __GNU_LIBRARY__ */ extern int getopt (); #endif /* __GNU_LIBRARY__ */ extern int getopt_long (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); extern int getopt_long_only (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); /* Internal only. Users should not call this directly. */ extern int _getopt_internal (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind, int long_only); #else /* not __STDC__ */ extern int getopt (); extern int getopt_long (); extern int getopt_long_only (); extern int _getopt_internal (); #endif /* __STDC__ */ #ifdef __cplusplus } #endif #endif /* _GETOPT_H */ ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/lib/getopt1.c ================================================ /* getopt_long and getopt_long_only entry points for GNU getopt. Copyright (C) 1987, 88, 89, 90, 91, 92, 1993, 1994 Free Software Foundation, Inc. This file is part of the GNU C Library. Its master source is NOT part of the C library, however. The master source lives in /gd/gnu/lib. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config.h" #ifndef HAVE_GETOPT_LONG #include "getopt.h" #if !defined (__STDC__) || !__STDC__ /* This is a separate conditional since some stdc systems reject `defined (const)'. */ #ifndef const #define const #endif #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #if defined (_LIBC) || !defined (__GNU_LIBRARY__) /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ #include #else char *getenv (); #endif #ifndef NULL #define NULL 0 #endif int getopt_long (argc, argv, options, long_options, opt_index) int argc; char *const *argv; const char *options; const struct option *long_options; int *opt_index; { return _getopt_internal (argc, argv, options, long_options, opt_index, 0); } /* Like getopt_long, but '-' as well as '--' can indicate a long option. If an option that starts with '-' (not '--') doesn't match a long option, but does match a short option, it is parsed as a short option instead. */ int getopt_long_only (argc, argv, options, long_options, opt_index) int argc; char *const *argv; const char *options; const struct option *long_options; int *opt_index; { return _getopt_internal (argc, argv, options, long_options, opt_index, 1); } #endif /* _LIBC or not __GNU_LIBRARY__. */ #ifdef TEST #include int main (argc, argv) int argc; char **argv; { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; int option_index = 0; static struct option long_options[] = { {"add", 1, 0, 0}, {"append", 0, 0, 0}, {"delete", 1, 0, 0}, {"verbose", 0, 0, 0}, {"create", 0, 0, 0}, {"file", 1, 0, 0}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "abc:d:0123456789", long_options, &option_index); if (c == EOF) break; switch (c) { case 0: printf ("option %s", long_options[option_index].name); if (optarg) printf (" with arg %s", optarg); printf ("\n"); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case 'd': printf ("option d with value `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); } #endif /* TEST */ #endif /* !HAVE_GETOPT_LONG */ ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/lib/ssl_writev.c ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by Martin Arlitt This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* This code is based on the generic writev() implementation of GNU libc. It implements writev() simply in terms of write(). No atomicity guarantees and performance isn't great either, but its good enough for SSL purposes. */ #include "config.h" #ifdef HAVE_OPENSSL_SSL_H #ifdef __FreeBSD__ #include #else #include #endif #include #include #include #include #include #include #include #include #include ssize_t SSL_writev (SSL *ssl, const struct iovec *vector, int count) { char *buffer; register char *bp; size_t bytes, to_copy; int i; /* Find the total number of bytes to be written. */ bytes = 0; for (i = 0; i < count; ++i) bytes += vector[i].iov_len; /* Allocate a temporary buffer to hold the data. */ buffer = (char *) alloca (bytes); /* Copy the data into BUFFER. */ to_copy = bytes; bp = buffer; for (i = 0; i < count; ++i) { # define min(a, b) ((a) > (b) ? (b) : (a)) size_t copy = min (vector[i].iov_len, to_copy); memcpy ((void *) bp, (void *) vector[i].iov_base, copy); bp += copy; to_copy -= copy; if (to_copy == 0) break; } return SSL_write (ssl, buffer, bytes); } #endif /* HAVE_OPENSSL_SSL_H */ ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/mkinstalldirs ================================================ #! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Last modified: 1994-03-25 # Public domain errstatus=0 for file in ${1+"$@"} ; do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d in ${1+"$@"} ; do pathcomp="$pathcomp$d" case "$pathcomp" in -* ) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" 1>&2 mkdir "$pathcomp" > /dev/null 2>&1 || lasterr=$? fi if test ! -d "$pathcomp"; then errstatus=$lasterr fi pathcomp="$pathcomp/" done done exit $errstatus # mkinstalldirs ends here ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/notes.txt ================================================ Timer info can be found looking for timer_now() Parameters for figuring out if a connection should be counted: 1. test_time_start - global for start of expt. 2. s->basic.time_connect_start - time that session (connection?) started 3. param.wsesslog.num_sessions - number of sessions from command line 4. param.timeout - command line argument 5. param.rate.rate_param - command line argument (--rate) expt_length = param.wsesslog.num_sessions / param.rate.rate_param check if expt_length > 2 * timeout! steady_state_start = test_time_start + timeout steady_state_end = test_time_start + expt_length - timeout HOW TO: 1. initialize steady_state_start and end 2. when a connection starts, check against steady_state_start & end, and set flag accordingly. 3. When statistics are counted/accumulated, check flag for which stats to produce. stats stuff is all in stats/basic.c? ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/object.c ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include #define ALIGN(s) (((s) + sizeof (double) - 1) & ~(sizeof (double) - 1)) static size_t type_size[OBJ_NUM_TYPES] = { ALIGN (sizeof (Conn)), ALIGN (sizeof (Call)), ALIGN (sizeof (Sess)) }; struct free_list_el { struct free_list_el *next; }; static struct free_list_el *free_list[OBJ_NUM_TYPES]; static void object_destroy (Object *obj) { Object_Type type = obj->type; struct free_list_el *el; Event_Type event = 0; Any_Type arg; switch (type) { case OBJ_CALL: call_deinit ((Call *) obj); event = EV_CALL_DESTROYED; break; case OBJ_CONN: conn_deinit ((Conn *) obj); event = EV_CONN_DESTROYED; break; case OBJ_SESS: sess_deinit ((Sess *) obj); event = EV_SESS_DESTROYED; break; default: assert (0); break; } arg.l = 0; event_signal (event, obj, arg); /* Each object must be at least the size and alignment of "struct free_list_el". Malloc takes care of returning properly aligned objects. */ el = (struct free_list_el *) obj; el->next = free_list[type]; free_list[type] = el; } size_t object_expand (Object_Type type, size_t size) { size_t offset = type_size[type]; type_size[type] += ALIGN (size); return offset; } Object * object_new (Object_Type type) { struct free_list_el *el; Event_Type event = 0; size_t obj_size; Any_Type arg; Object *obj; obj_size = type_size[type]; if (free_list[type]) { el = free_list[type]; free_list[type] = el->next; obj = (Object *) el; } else { obj = malloc (obj_size); if (!obj) { fprintf (stderr, "%s.object_new: %s\n", prog_name, strerror (errno)); return 0; } } memset (obj, 0, obj_size); obj->ref_count = 1; obj->type = type; switch (type) { case OBJ_CALL: call_init ((Call *) obj); event = EV_CALL_NEW; break; case OBJ_CONN: conn_init ((Conn *) obj); event = EV_CONN_NEW; break; case OBJ_SESS: sess_init ((Sess *) obj); event = EV_SESS_NEW; break; default: panic ("object_new: bad object type %d\n", type); break; } arg.l = 0; event_signal (event, obj, arg); return obj; } void object_dec_ref (Object *obj) { assert (obj->ref_count > 0); if (--obj->ref_count == 0) object_destroy (obj); } ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/object.h ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef object_h #define object_h #ifdef DEBUG # define object_is_conn(o) (((Object *) (o))->type == OBJ_CONN) # define object_is_call(o) (((Object *) (o))->type == OBJ_CALL) # define object_is_sess(o) (((Object *) (o))->type == OBJ_SESS) #else # define object_is_conn(o) 1 # define object_is_call(o) 1 # define object_is_sess(o) 1 #endif typedef enum Object_Type { OBJ_CONN, /* connection object */ OBJ_CALL, /* call object */ OBJ_SESS, /* session object */ OBJ_NUM_TYPES } Object_Type; typedef struct Object { Object_Type type; u_int ref_count; /* # of references to this object */ } Object; /* This may be called during httperf initialize to reserve SIZE "private" bytes in objects of type TYPE. The return value is the offset of the private area. */ extern size_t object_expand (Object_Type type, size_t size); /* Create a new object of type TYPE. */ extern Object *object_new (Object_Type type); /* Create a new reference for object OBJ. */ #define object_inc_ref(o) (++(o)->ref_count) /* Decrement the reference for object OBJ. If the reference count reaches zero, the object's destroy function is called. */ extern void object_dec_ref (Object *obj); #endif /* object_h */ ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/out_1080p_0.txt ================================================ -bash: ../build_orig/httperf: No such file or directory ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/output.log ================================================ Total: connections 100 requests 1547 replies 1547 test-duration 204.918 s Number of connected connections is currently = 0 Connection rate: 0.5 conn/s (2049.2 ms/conn, <=100 concurrent connections) Connected connection rate: 0.5 conn/s (2049.2 ms/conn, <=100 concurrent connected connections) Connection time [ms]: min 30036.8 avg 114802.3 max 180179.4 median 99999.5 stddev 64578.5 Connection time [ms]: connect 0.0 Connection length [replies/conn]: 15.470 Response time (no timeouts) [ms]: 0.0 Response time (only timeouts) [ms]: 0.0 Response time (all) [ms]: 114802.3 Request rate: 7.5 req/s (132.5 ms/req) Request size [B]: 131.0 Overall reply rate: 7.5 replies/sec Reply rate [replies/s]: min 1.4 avg 7.7 max 24.0 stddev 5.0 (40 samples) Reply time [ms]: response 0.2 transfer 5.9 Reply size [B]: header 256.0 content 496711.0 footer 0.0 (total 496967.0) Reply status: 1xx=0 2xx=1547 3xx=0 4xx=0 5xx=0 CPU time [s]: user 0.68 system 3.06 (user 0.3% system 1.5% total 1.8%) Net I/O: 3664.8 KB/s (30.0*10^6 bps) Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0 Errors: fd-unavail 0 addrunavail 0 ftab-full 0 addrinuse 0 other 0 Unconnected timeouts 0 connected timeouts 0 total (0) client_timeouts 0 Session rate [sess/s]: min 0.00 avg 0.49 max 1.60 stddev 0.66 (100/100) Session: avg 1.00 connections/session Session lifetime [s]: 114.8 Session failtime [s]: 0.0 Session length histogram: 0 0 0 0 0 0 0 35 0 0 0 0 0 0 0 0 0 0 32 0 0 0 33 ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/run-httperf ================================================ #!/bin/csh build-linux/httperf --verbose --timeout=2 --client=0/12 --server=192.168.41.110 --port=6800 --uri=/test/ --rate=3 --send-buffer=4096 --recv-buffer=1048576 --call-stats=30 --call-stats-file=/home/jasummer/logs/call-stats-5000x100Mb --wsesslog=25,0.000,/home/jasummer/logs/cl-pop3-25x1x100Mb-00.log --ramp-up-time=1 --ramp-down-time=1 ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/sess.c ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include void sess_init (Sess *sess) { #ifdef HAVE_SSL sess->use_ssl = 0; #endif /* HAVE_SSL */ } void sess_deinit (Sess *sess) { #ifdef HAVE_SSL if (sess->ssl) SSL_free (sess->ssl); #endif } void sess_failure (Sess *sess) { Any_Type arg; if (sess->failed) return; sess->failed = 1; arg.l = 0; event_signal (EV_SESS_FAILED, (Object *) sess, arg); sess_dec_ref (sess); } ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/sess.h ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef sess_h #define sess_h #include #include #include #ifdef HAVE_SSL # include #endif /* Sessions are not used by the httperf's core itself, but they are provided here for the benefit of workload generators that need such a notion (e.g., to represent users). */ typedef struct Sess { Object obj; #ifdef HAVE_SSL SSL *ssl; /* SSL session (or NULL) */ int use_ssl; /* use ssl=1,don't use ssl=2,default=other */ #endif /* HAVE_SSL */ u_int failed : 1; /* did session fail? */ int num_requests; /* The number of requests in this session*/ int port; /* port to use for connections, 0 => use default */ const char *server; /*server to use for connections, NULL => use default */ int log_index; char local_ip[16]; } Sess; /* Initialize the new session object S. */ extern void sess_init (Sess *s); /* Destroy the session-specific state in session object S. */ extern void sess_deinit (Sess *s); /* Session S failed. This causes EV_SESS_FAILED to be signalled and gives up the caller's reference to S. */ extern void sess_failure (Sess *s); #define sess_new() ((Sess *) object_new (OBJ_SESS)) #define sess_inc_ref(s) object_inc_ref ((Object *) (s)) #define sess_dec_ref(s) object_dec_ref ((Object *) (s)) #endif /* sess_h */ ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/stat/Makefile ================================================ # Generated automatically from Makefile.in by configure. SHELL=/bin/sh srcdir = . top_srcdir = .. top_builddir = .. prefix = /usr/local bindir = ${exec_prefix}/bin mandir = ${prefix}/man CC = gcc RANLIB = ranlib INCLUDES = -I$(top_builddir) -I$(srcdir) -I$(top_srcdir) -I$(top_srcdir)/lib \ -I$(top_srcdir)/gen $(SSL_INCLUDES) -I/usr/kerberos/include DEFS = -DHAVE_CONFIG_H CPPFLAGS = -DNDEBUG -D_GNU_SOURCE -D_XOPEN_SOURCE CFLAGS = -g -O2 -Wall LDFLAGS = LIBS = -lssl -lcrypto -lm # Uncomment this to enable tracking statistics about each call (request) DEFS += -DUW_CALL_STATS # Uncomment this to enable session log file specified dynamic timeouts DEFS += -DUW_DYNOUT -DHAVE_EPOLL # Uncomment this to enable "pace_time" in wsesslog files DEFS += -DUW_PACE_REQUESTS # Uncomment this to enable statistics that ignore specified ramp up and ramp down periods #DEFS += -DUW_STABLE_STATS # Uncomment this to generate stats about the variation in throughput DEFS += -DUW_THROUGHPUT_STATS CPPFLAGS += -DBIG_FD_SETSIZE COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -static -static-libgcc LINK = $(CC) $(LDFLAGS) -static -static-libgcc -o $@ .c.o: $(COMPILE) $< LIBSTAT_OBJS = basic.o sess_stat.o print_reply.o spec_stats.o call_stats.o all: libstat.a libstat.a: $(LIBSTAT_OBJS) ar r $@ $(LIBSTAT_OBJS) $(RANLIB) $@ depend: install: clean: rm -f libstat.a $(LIBSTAT_OBJS) distclean: clean rm -f *~ .PHONY: all install clean distclean depend ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/stat/Makefile.in ================================================ SHELL=/bin/sh VPATH = @srcdir@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ top_builddir = .. prefix = @prefix@ bindir = @bindir@ mandir = @mandir@ CC = @CC@ RANLIB = @RANLIB@ INCLUDES = -I$(top_builddir) -I$(srcdir) -I$(top_srcdir) -I$(top_srcdir)/lib \ -I$(top_srcdir)/gen $(SSL_INCLUDES) -I/usr/kerberos/include DEFS = @DEFS@ CPPFLAGS = @CPPFLAGS@ CFLAGS = @CFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ # Uncomment this to enable tracking statistics about each call (request) DEFS += -DUW_CALL_STATS # Uncomment this to enable session log file specified dynamic timeouts DEFS += -DUW_DYNOUT -DHAVE_EPOLL # Uncomment this to enable "pace_time" in wsesslog files DEFS += -DUW_PACE_REQUESTS # Uncomment this to enable statistics that ignore specified ramp up and ramp down periods #DEFS += -DUW_STABLE_STATS # Uncomment this to generate stats about the variation in throughput DEFS += -DUW_THROUGHPUT_STATS CPPFLAGS += -DBIG_FD_SETSIZE COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -static -static-libgcc LINK = $(CC) $(LDFLAGS) -static -static-libgcc -o $@ @SET_MAKE@ .c.o: $(COMPILE) $< LIBSTAT_OBJS = basic.o sess_stat.o print_reply.o spec_stats.o call_stats.o all: libstat.a libstat.a: $(LIBSTAT_OBJS) ar r $@ $(LIBSTAT_OBJS) $(RANLIB) $@ depend: install: clean: rm -f libstat.a $(LIBSTAT_OBJS) distclean: clean rm -f *~ .PHONY: all install clean distclean depend ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/stat/basic.c ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Basic statistics collector. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef UW_CALL_STATS #include #endif /* UW_CALL_STATS */ extern Cmdline_Params param; /* Increase this if it does not cover at least 50% of all response times. */ #define MAX_LIFETIME 100.0 /* max. conn. lifetime in seconds */ #define BIN_WIDTH 1e-3 /* !! CHANGE CODE BELOW IF YOU CHANGE THESE */ #ifdef OLDWAY /* Newer compilers complain about this */ #define NUM_BINS ((u_int) (MAX_LIFETIME / BIN_WIDTH)) #else /* NOTE THIS SHOULD BE CALCULATED FROM ABOVE VALUES */ /* MAX_LIFETIME / BIN_WIDTH */ #define NUM_BINS (100000) #endif unsigned int *errno_errs_reported = 0; unsigned int *httperf_errs_reported = 0; #define MAX_ERRNO (500) void print_errno_info(); /* #define LOCAL_DEBUG */ #ifdef LOCAL_DEBUG void print_connected_info(char *func, int sd, int state); #define ldbg(...) \ do {\ printf(__VA_ARGS__); \ fflush(stdout); \ fflush(stderr); \ } while (0); #else #define ldbg(...) #define print_connected_info(a, b, c) #endif /* LOCAL_DEBUG */ static struct { u_int num_conns_issued; /* total # of connections issued */ u_int num_replies[6]; /* completion count per status class */ u_int num_client_timeouts; /* # of client timeouts */ u_int num_sock_fdunavail; /* # of times out of filedescriptors */ u_int num_sock_ftabfull; /* # of times file table was full */ u_int num_sock_refused; /* # of ECONNREFUSED */ u_int num_sock_reset; /* # of ECONNRESET */ u_int num_sock_timeouts; /* # of ETIMEDOUT */ u_int num_sock_addrunavail;/* # of EADDRNOTAVAIL */ u_int num_sock_addrinuse; /* # of EADDRINUSE */ u_int num_other_errors; /* # of other errors */ u_int max_conns; /* max # of concurrent connections */ int max_connected_conns; /* max # of concurrent connected connections */ int num_connected_conns; /* # of concurrent connected connections */ int num_total_connected_conns; int num_client_connected_timeouts; /* timeout happened after connection was established */ int num_client_unconnected_timeouts; /* timeout happened before connection was established */ u_int num_lifetimes; Time conn_lifetime_sum; /* sum of connection lifetimes */ Time conn_lifetime_sum2; /* sum of connection lifetimes squared */ Time conn_lifetime_min; /* minimum connection lifetime */ Time conn_lifetime_max; /* maximum connection lifetime */ Time conn_lifetime_sum_notm; /* sum of conn lifetimes for conns that don't time out */ Time conn_lifetime_sum_tm; /* sum of conn lifetimes for conns that do time out */ int timeout_replies; /* num replies recvd from conns that eventually timed out */ int no_timeout_replies; /* num replies recvd from conns tha did not time out */ #ifdef UW_STABLE_STATS /* keep track of stats for the entire experiment, not just stable time */ u_int all_conns_issued; /* total # of connections issued */ int num_total_all_conns; int max_all_conns; /* max # of concurrent connected connections */ u_int num_all_sent; /* # of requests sent */ u_int num_all_replies; /* completion count for all connections */ u_int all_num_lifetimes; Time all_lifetime_sum; /* sum of connection lifetimes */ Time all_lifetime_sum2; /* sum of connection lifetimes squared */ Time all_lifetime_min; /* minimum connection lifetime */ Time all_lifetime_max; /* maximum connection lifetime */ Time all_lifetime_sum_notm; /* sum of conn lifetimes for conns that don't time out */ Time all_lifetime_sum_tm; /* sum of conn lifetimes for conns that do time out */ int all_timeout_replies; /* num replies recvd from conns that eventually timed out */ int all_no_timeout_replies; /* num replies recvd from conns tha did not time out */ u_int is_stable; /* true when not ramping up or ramping down */ #endif /* UW_STABLE_STATS */ u_int num_reply_samples; Time reply_rate_sum; Time reply_rate_sum2; Time reply_rate_min; Time reply_rate_max; #ifdef UW_THROUGHPUT_STATS double throughput_sum; double throughput_sum2; double throughput_min; double throughput_max; #endif /* UW_THROUGHPUT_STATS */ u_int num_connects; /* # of completed connect()s */ Time conn_connect_sum; /* sum of connect times */ u_int num_responses; Time call_response_sum; /* sum of response times */ Time call_xfer_sum; /* sum of response times */ u_int num_sent; /* # of requests sent */ size_t req_bytes_sent; u_wide hdr_bytes_received; /* sum of all header bytes */ u_wide reply_bytes_received; /* sum of all data bytes */ u_wide footer_bytes_received; /* sum of all footer bytes */ #ifdef UW_STABLE_STATS u_wide all_hdr_bytes_received; /* sum of all header bytes */ u_wide all_reply_bytes_received; /* sum of all data bytes */ u_wide all_footer_bytes_received; /* sum of all footer bytes */ #endif /* UW_STABLE_STATS */ u_int conn_lifetime_hist[NUM_BINS]; /* histogram of connection lifetimes */ u_int num_active_conns[MAX_LOG_FILES]; } basic; static u_int num_active_conns; static u_int num_replies; /* # of replies received in this interval */ #ifdef UW_THROUGHPUT_STATS static u_wide bytes_received; /* number of bytes received in this interval */ #endif /* UW_THROUGHPUT_STATS */ #ifdef UW_STABLE_STATS static long stable_conns_start; /* number of connections to ignore at beginning */ static long stable_conns_end; /* ignore connections starting from this id */ #endif /* UW_STABLE_STATS */ int started_dump_stats = 0; static void perf_sample (Event_Type et, Object *obj, Any_Type reg_arg, Any_Type call_arg) { Time weight = call_arg.d; double rate; int i = 0; assert (et == EV_PERF_SAMPLE); rate = weight*num_replies; if (!started_dump_stats) { if(verbose) { printf("Benchmark stats...\n"); } started_dump_stats = 1; } if(verbose){ printf("\n\n\n"); for (i=0; i < MAX_LOG_FILES; i++) { printf("%d ", basic.num_active_conns[i]); } printf("\n"); } // aansaarii int total_errors = basic.num_client_timeouts + basic.num_sock_timeouts + basic.num_sock_fdunavail + basic.num_sock_ftabfull + basic.num_sock_refused + basic.num_sock_reset + basic.num_sock_addrunavail + basic.num_sock_addrinuse + basic.num_other_errors; #ifdef UW_THROUGHPUT_STATS /* convert throughput into Mbps */ double throughput = weight * bytes_received * 8.0 / 1000000; printf("Throughput (Mbps) = %-8.2lf, total-errors = %-8d, concurrent-clients = %-8d, reply-rate = %-8.1lf\n", throughput, total_errors, basic.num_connected_conns, rate); fflush(stdout); #else printf("reply-rate (conn/s) = %-8.1f, total-errors = %-8d, concurrent-clients = %-8d\n", rate, total_errors, basic.num_connected_conns); fflush(stdout); #endif /* UW_THROUGHPUT_STATS */ #ifdef UW_STABLE_STATS if (basic.is_stable) #endif /* UW_STABLE_STATS */ { basic.reply_rate_sum += rate; basic.reply_rate_sum2 += SQUARE (rate); if (rate < basic.reply_rate_min) basic.reply_rate_min = rate; if (rate > basic.reply_rate_max) basic.reply_rate_max = rate; ++basic.num_reply_samples; #ifdef UW_THROUGHPUT_STATS basic.throughput_sum += throughput; basic.throughput_sum2 += SQUARE (throughput); if (throughput < basic.throughput_min) basic.throughput_min = throughput; if (throughput > basic.throughput_max) basic.throughput_max = throughput; #endif /* UW_THROUGHPUT_STATS */ } /* prepare for next sample interval: */ num_replies = 0; #ifdef UW_THROUGHPUT_STATS bytes_received = 0; #endif /* UW_THROUGHPUT_STATS */ } static void conn_timeout (Event_Type et, Object *obj, Any_Type reg_arg, Any_Type call_arg) { Conn *s = (Conn *) obj; assert (et == EV_CONN_TIMEOUT); s->timed_out = 1; #ifdef UW_CALL_STATS s->basic.time_of_timeout = timer_now(); #endif /* UW_CALL_STATS */ #ifdef UW_STABLE_STATS if (s->basic.is_stable) { ++basic.num_client_timeouts; if ((s->state >= S_CONNECTED) && (s->sd > 0)) { ++basic.num_client_connected_timeouts; } else { ++basic.num_client_unconnected_timeouts; } } #else ++basic.num_client_timeouts; if ((s->state >= S_CONNECTED) && (s->sd > 0)) { ++basic.num_client_connected_timeouts; } else { ++basic.num_client_unconnected_timeouts; } #endif /* UW_STABLE_STATS */ if( param.spec_stats > 0 ) { process_spec_timeout( s ); } #ifdef UW_CALL_STATS if( param.call_stats >= 0 ) { process_call_timeout( s ); } #endif /* UW_CALL_STATS */ print_connected_info(__FUNCTION__, s->sd, s->state); } static void conn_close(Event_Type et, Object *obj, Any_Type reg_arg, Any_Type call_arg) { Conn *s = (Conn *) obj; int prev_state = call_arg.i; /* only decrement the count if the connection was connected * and the socket descriptor is still valid. * If these aren't true then the connection wasn't actually * established and it hasn't been counted. */ if ((prev_state >= S_CONNECTED) && (s->sd > 0)) { --basic.num_connected_conns; } print_connected_info(__FUNCTION__, s->sd, prev_state); } static void conn_fail (Event_Type et, Object *obj, Any_Type reg_arg, Any_Type call_arg) { #ifdef LOCAL_DEBUG Conn *s = (Conn *) obj; #endif /* static int first_time = 1; */ int err = call_arg.i; int index = -1; assert (et == EV_CONN_FAILED); print_connected_info(__FUNCTION__, s->sd, s->state); switch (err) { #ifdef __linux__ case EINVAL: /* Linux has a strange way of saying "out of fds"... */ #endif case EMFILE: ++basic.num_sock_fdunavail; break; case ENFILE: ++basic.num_sock_ftabfull; break; case ECONNREFUSED: ++basic.num_sock_refused; break; case ETIMEDOUT: ++basic.num_sock_timeouts; break; case EADDRINUSE: ++basic.num_sock_addrinuse; break; case EPIPE: case ECONNRESET: ++basic.num_sock_reset; break; default: ++basic.num_other_errors; if (err < 0) { index = -err; httperf_errs_reported[index] += 1; if (httperf_errs_reported[index] == 1) { switch (err) { case CONN_ERR_NOT_SET: fprintf (stderr, "%s: connection failed but error value wasn't set properly\n", prog_name); break; case CONN_ERR_NO_MORE_PORTS: fprintf (stderr, "%s: connection failed because no ports were available\n", prog_name); /* fprintf(stderr, "index = %d count = %d\n", index, httperf_errs_reported[index]); */ break; case CONN_ERR_HASH_LOOKUP_FAILED: fprintf (stderr, "%s: connection failed because hash_lookup failed\n", prog_name); break; case CONN_ERR_STATE_PAST_CLOSING: fprintf (stderr, "%s: connection failed because of incorrect state\n", prog_name); break; default: fprintf (stderr, "%s: connection failed with unexpected error %d\n", prog_name, err); } } } else { errno_errs_reported[err]++; if (errno_errs_reported[err] == 1) { fprintf (stderr, "%s: connection failed with unexpected error %d\n", prog_name, err); } } break; } } static void conn_created (Event_Type et, Object *obj, Any_Type reg_arg, Any_Type c_arg) { ++num_active_conns; if (num_active_conns > basic.max_conns) basic.max_conns = num_active_conns; } static void conn_connecting (Event_Type et, Object *obj, Any_Type reg_arg, Any_Type c_arg) { Conn *s = (Conn *) obj; basic.num_active_conns[s->log_index]++; assert (et == EV_CONN_CONNECTING && object_is_conn (s)); s->basic.time_connect_start = timer_now (); #ifdef UW_STABLE_STATS // printf("s->id = %ld\n", s->id); // printf("stable_conns_start = %ld\n", stable_conns_start); // printf("stable_conns_end = %ld\n", stable_conns_end); if (((long) s->id >= stable_conns_start) && ((long) s->id < stable_conns_end)) { // printf("is stable\n"); basic.is_stable = 1; s->basic.is_stable = 1; ++basic.num_conns_issued; } else { // printf("is NOT stable\n"); basic.is_stable = 0; s->basic.is_stable = 0; } ++basic.all_conns_issued; #else ++basic.num_conns_issued; #endif /* UW_STABLE_STATS */ } static void conn_connected (Event_Type et, Object *obj, Any_Type reg_arg, Any_Type call_arg) { Conn *s = (Conn *) obj; assert (et == EV_CONN_CONNECTED && object_is_conn (s)); #ifdef UW_CALL_STATS s->basic.time_to_connect = timer_now () - s->basic.time_connect_start; basic.conn_connect_sum += s->basic.time_to_connect; #else basic.conn_connect_sum += timer_now () - s->basic.time_connect_start; #endif /* UW_CALL_STATS */ ++basic.num_connects; if (s->state >= S_CONNECTED) { ++basic.num_connected_conns; #ifdef UW_STABLE_STATS if (s->basic.is_stable) { ++basic.num_total_connected_conns; if (basic.num_connected_conns > basic.max_connected_conns) { basic.max_connected_conns = basic.num_connected_conns; } } ++basic.num_total_all_conns; if (basic.num_connected_conns > basic.max_all_conns) { basic.max_all_conns = basic.num_connected_conns; } #else ++basic.num_total_connected_conns; if (basic.num_connected_conns > basic.max_connected_conns) { basic.max_connected_conns = basic.num_connected_conns; } #endif /* UW_STABLE_STATS */ } if( param.spec_stats > 0 ) { track_spec_connection( s ); } print_connected_info(__FUNCTION__, s->sd, s->state); } static void conn_destroyed (Event_Type et, Object *obj, Any_Type reg_arg, Any_Type c_arg) { Conn *s = (Conn *) obj; Time lifetime; u_int bin; assert (et == EV_CONN_DESTROYED && object_is_conn (s) && num_active_conns > 0); lifetime = timer_now () - s->basic.time_connect_start; basic.num_active_conns[s->log_index]--; #ifdef UW_STABLE_STATS if( s->timed_out ) { basic.all_lifetime_sum_tm += lifetime; basic.all_timeout_replies += s->basic.num_calls_completed; } else { basic.all_lifetime_sum_notm += lifetime; basic.all_no_timeout_replies += s->basic.num_calls_completed; } if (s->basic.num_calls_completed > 0) { basic.all_lifetime_sum += lifetime; basic.all_lifetime_sum2 += SQUARE (lifetime); if (lifetime < basic.all_lifetime_min) basic.all_lifetime_min = lifetime; if (lifetime > basic.all_lifetime_max) basic.all_lifetime_max = lifetime; ++basic.all_num_lifetimes; } if (s->basic.is_stable) { if( s->timed_out ) { basic.conn_lifetime_sum_tm += lifetime; basic.timeout_replies += s->basic.num_calls_completed; } else { basic.conn_lifetime_sum_notm += lifetime; basic.no_timeout_replies += s->basic.num_calls_completed; } if (s->basic.num_calls_completed > 0) { basic.conn_lifetime_sum += lifetime; basic.conn_lifetime_sum2 += SQUARE (lifetime); if (lifetime < basic.conn_lifetime_min) basic.conn_lifetime_min = lifetime; if (lifetime > basic.conn_lifetime_max) basic.conn_lifetime_max = lifetime; ++basic.num_lifetimes; bin = lifetime*NUM_BINS/MAX_LIFETIME; if (bin >= NUM_BINS) bin = NUM_BINS-1; ++basic.conn_lifetime_hist[bin]; } } #else if( s->timed_out ) { basic.conn_lifetime_sum_tm += lifetime; basic.timeout_replies += s->basic.num_calls_completed; } else { basic.conn_lifetime_sum_notm += lifetime; basic.no_timeout_replies += s->basic.num_calls_completed; } if (s->basic.num_calls_completed > 0) { basic.conn_lifetime_sum += lifetime; basic.conn_lifetime_sum2 += SQUARE (lifetime); if (lifetime < basic.conn_lifetime_min) basic.conn_lifetime_min = lifetime; if (lifetime > basic.conn_lifetime_max) basic.conn_lifetime_max = lifetime; ++basic.num_lifetimes; bin = lifetime*NUM_BINS/MAX_LIFETIME; if (bin >= NUM_BINS) bin = NUM_BINS-1; ++basic.conn_lifetime_hist[bin]; } #endif /* UW_STABLE_STATS */ --num_active_conns; } static void send_start (Event_Type et, Object *obj, Any_Type reg_arg, Any_Type call_arg) { Call *c = (Call *) obj; assert (et == EV_CALL_SEND_START && object_is_call (c)); c->basic.time_send_start = timer_now (); } static void send_stop (Event_Type et, Object *obj, Any_Type reg_arg, Any_Type call_arg) { Call *c = (Call *) obj; assert (et == EV_CALL_SEND_STOP && object_is_call (c)); #ifdef UW_STABLE_STATS if (basic.is_stable) { basic.req_bytes_sent += c->req.size; ++basic.num_sent; } ++basic.num_all_sent; #else basic.req_bytes_sent += c->req.size; ++basic.num_sent; #endif /* UW_STABLE_STATS */ if( param.spec_stats > 0 ) { track_spec_request(c); } #ifdef UW_CALL_STATS if( param.call_stats>= 0 ) { track_call_request(c); } #endif /* UW_CALL_STATS */ } static void recv_start (Event_Type et, Object *obj, Any_Type reg_arg, Any_Type call_arg) { Call *c = (Call *) obj; Time now; double resp_time = 0.0; assert (et == EV_CALL_RECV_START && object_is_call (c)); now = timer_now (); resp_time = now - c->basic.time_send_start; c->basic.time_recv_start = now; #ifdef UW_STABLE_STATS if (basic.is_stable) { basic.call_response_sum += resp_time; ++basic.num_responses; } #else basic.call_response_sum += resp_time; ++basic.num_responses; #endif /* UW_STABLE_STATS */ if( param.spec_stats > 0 ) { track_spec_response( c, resp_time ); } } static void recv_stop (Event_Type et, Object *obj, Any_Type reg_arg, Any_Type call_arg) { Call *c = (Call *) obj; int index; double transfer_time = 0.0; assert (et == EV_CALL_RECV_STOP && object_is_call (c)); assert (c->basic.time_recv_start > 0); transfer_time = timer_now () - c->basic.time_recv_start; #ifdef UW_STABLE_STATS if (basic.is_stable) { basic.call_xfer_sum += transfer_time; basic.hdr_bytes_received += c->reply.header_bytes; basic.reply_bytes_received += c->reply.content_bytes; basic.footer_bytes_received += c->reply.footer_bytes; index = (c->reply.status / 100); assert ((unsigned) index < NELEMS (basic.num_replies)); ++basic.num_replies[index]; } ++basic.num_all_replies; basic.all_hdr_bytes_received += c->reply.header_bytes; basic.all_reply_bytes_received += c->reply.content_bytes; basic.all_footer_bytes_received += c->reply.footer_bytes; #else basic.call_xfer_sum += transfer_time; basic.hdr_bytes_received += c->reply.header_bytes; basic.reply_bytes_received += c->reply.content_bytes; basic.footer_bytes_received += c->reply.footer_bytes; index = (c->reply.status / 100); assert ((unsigned) index < NELEMS (basic.num_replies)); ++basic.num_replies[index]; #endif /* UW_STABLE_STATS */ #ifdef UW_THROUGHPUT_STATS /* track total number of bytes received during interval */ bytes_received += c->reply.header_bytes + c->reply.content_bytes + c->reply.footer_bytes; #endif /* UW_THROUGHPUT_STATS */ ++num_replies; ++c->conn->basic.num_calls_completed; if ( param.spec_stats > 0 ) { track_spec_reply( c, transfer_time ); } #ifdef UW_CALL_STATS if ( param.call_stats >= 0 ) { track_call_reply( c, transfer_time ); } #endif /* UW_CALL_STATS */ } static void dump_stats (Event_Type et, Object *obj, Any_Type req_arg, Any_Type call_arg) { if(!verbose){ return; } Time conn_period = 0.0, call_period = 0.0; Time conn_time = 0.0, resp_time = 0.0, xfer_time = 0.0; Time call_size = 0.0, hdr_size = 0.0, reply_size = 0.0, footer_size = 0.0; Time lifetime_avg = 0.0, lifetime_stddev = 0.0, lifetime_median = 0.0; double avg = 0.0, stddev = 0.0; int i, total_replies = 0; Time delta, user, sys; u_wide total_size; Time time; u_int n; assert (et == EV_DUMP_STATS); for (i = 1; i < NELEMS (basic.num_replies); ++i) total_replies += basic.num_replies[i]; #ifdef UW_STABLE_STATS delta = timer_now() - test_time_start; if (basic.is_stable && stable_conns_start >= 0) { /* subtract time it took to become stable */ delta -= stable_conns_start * param.rate.mean_iat; } #else delta = timer_now() - test_time_start; #endif /* UW_STABLE_STATS */ if (verbose > 1) { printf ("\nConnection lifetime histogram (time in ms):\n"); for (i = 0; i < NUM_BINS; ++i) if (basic.conn_lifetime_hist[i]) { if (i > 0 && basic.conn_lifetime_hist[i - 1] == 0) printf ("%14c\n", ':'); time = (i + 0.5)*BIN_WIDTH; printf ("%16.1f %u\n", 1e3*time, basic.conn_lifetime_hist[i]); } } printf ("\nTotal: connections %u requests %u replies %u " "test-duration %.3f s\n", basic.num_conns_issued, basic.num_sent, total_replies, delta); printf("Number of connected connections is currently = %d\n", basic.num_connected_conns); if (basic.num_connected_conns != 0) { printf("WARNING: was expecting 0 and got %d\n", basic.num_connected_conns); } putchar ('\n'); if (basic.num_conns_issued) conn_period = delta/basic.num_conns_issued; printf ("Connection rate: %.1f conn/s (%.1f ms/conn, " "<=%u concurrent connections)\n", basic.num_conns_issued / delta, 1e3*conn_period, basic.max_conns); printf ("Connected connection rate: %.1f conn/s (%.1f ms/conn, " "<=%d concurrent connected connections)\n", basic.num_total_connected_conns / delta, 1e3*conn_period, basic.max_connected_conns); if (basic.num_lifetimes > 0) { lifetime_avg = (basic.conn_lifetime_sum / basic.num_lifetimes); if (basic.num_lifetimes > 1) lifetime_stddev = STDDEV (basic.conn_lifetime_sum, basic.conn_lifetime_sum2, basic.num_lifetimes); n = 0; for (i = 0; i < NUM_BINS; ++i) { n += basic.conn_lifetime_hist[i]; if (n >= 0.5*basic.num_lifetimes) { lifetime_median = (i + 0.5)*BIN_WIDTH; break; } } } else { lifetime_avg = param.timeout; lifetime_median = param.timeout; } printf ("Connection time [ms]: min %.1f avg %.1f max %.1f median %.1f " "stddev %.1f\n", basic.num_lifetimes > 0 ? 1e3 * basic.conn_lifetime_min : 0.0, 1e3 * lifetime_avg, 1e3 * basic.conn_lifetime_max, 1e3 * lifetime_median, 1e3 * lifetime_stddev); if (basic.num_connects > 0) conn_time = basic.conn_connect_sum / basic.num_connects; printf ("Connection time [ms]: connect %.1f\n", 1e3*conn_time); printf ("Connection length [replies/conn]: %.3f\n", basic.num_lifetimes > 0 ? total_replies/ (double) basic.num_lifetimes : 0.0); putchar ('\n'); #ifdef UW_STABLE_STATS lifetime_avg = 0.0; lifetime_stddev = 0.0; lifetime_median = 0.0; if (basic.all_num_lifetimes > 0) { lifetime_avg = basic.all_lifetime_sum / basic.all_num_lifetimes; if (basic.all_num_lifetimes > 1) lifetime_stddev = STDDEV (basic.all_lifetime_sum, basic.all_lifetime_sum2, basic.all_num_lifetimes); } printf ("All Conn time [ms]: min %.1f avg %.1f max %.1f median %.1f " "stddev %.1f\n", basic.all_num_lifetimes > 0 ? 1e3 * basic.all_lifetime_min : 0.0, 1e3 * lifetime_avg, 1e3 * basic.all_lifetime_max, 1e3 * lifetime_median, 1e3 * lifetime_stddev); putchar ('\n'); #endif /* UW_STABLE_STATS */ if (basic.num_sent > 0) call_period = delta/basic.num_sent; printf ("Request rate: %.1f req/s (%.1f ms/req)\n", basic.num_sent / delta, 1e3*call_period); if (basic.num_sent) call_size = basic.req_bytes_sent / basic.num_sent; printf ("Request size [B]: %.1f\n", call_size); putchar ('\n'); if (basic.num_reply_samples > 0) { avg = (basic.reply_rate_sum / basic.num_reply_samples); if (basic.num_reply_samples > 1) stddev = STDDEV (basic.reply_rate_sum, basic.reply_rate_sum2, basic.num_reply_samples); } printf ("Reply rate [replies/s]: min %.1f avg %.1f max %.1f stddev %.1f " "(%u samples)\n", basic.num_reply_samples > 0 ? basic.reply_rate_min : 0.0, avg, basic.reply_rate_max, stddev, basic.num_reply_samples); #ifdef UW_THROUGHPUT_STATS avg = 0.0; stddev = 0.0; if (basic.num_reply_samples > 0) { avg = (basic.throughput_sum / basic.num_reply_samples); if (basic.num_reply_samples > 1) stddev = STDDEV (basic.throughput_sum, basic.throughput_sum2, basic.num_reply_samples); } printf ("Throughput [Mbps]: min %.2f avg %.2f max %.2f stddev %.2f " "(%u samples)\n", basic.num_reply_samples > 0 ? basic.throughput_min : 0.0, avg, basic.throughput_max, stddev, basic.num_reply_samples); #endif /* UW_THROUGHPUT_STATS */ if (basic.num_responses > 0) resp_time = basic.call_response_sum / basic.num_responses; if (total_replies > 0) xfer_time = basic.call_xfer_sum / total_replies; else { /* if no responses, asssume transfer time is the timeout period */ xfer_time = param.timeout; } printf ("Reply time [ms]: response %.1f transfer %.1f\n", 1e3*resp_time, 1e3*xfer_time); if (total_replies) { hdr_size = basic.hdr_bytes_received / total_replies; reply_size = basic.reply_bytes_received / total_replies; footer_size = basic.footer_bytes_received / total_replies; } printf ("Reply size [B]: header %.1f content %.1f footer %.1f " "(total %.1f)\n", hdr_size, reply_size, footer_size, hdr_size + reply_size + footer_size); printf ("Reply status: 1xx=%u 2xx=%u 3xx=%u 4xx=%u 5xx=%u\n", basic.num_replies[1], basic.num_replies[2], basic.num_replies[3], basic.num_replies[4], basic.num_replies[5]); putchar ('\n'); user = (TV_TO_SEC (test_rusage_stop.ru_utime) - TV_TO_SEC (test_rusage_start.ru_utime)); sys = (TV_TO_SEC (test_rusage_stop.ru_stime) - TV_TO_SEC (test_rusage_start.ru_stime)); printf ("CPU time [s]: user %.2f system %.2f (user %.1f%% system %.1f%% " "total %.1f%%)\n", user, sys, 100.0*user/delta, 100.0*sys/delta, 100.0*(user + sys)/delta); total_size = (basic.req_bytes_sent + basic.hdr_bytes_received + basic.reply_bytes_received); printf ("Net I/O: %.1f KB/s (%.1f*10^6 bps)\n", total_size/delta / 1024.0, 8e-6*total_size/delta); putchar ('\n'); printf ("Errors: total %u client-timo %u socket-timo %u " "connrefused %u connreset %u\n" "Errors: fd-unavail %u addrunavail %u ftab-full %u " "addrinuse %u other %u\n", (basic.num_client_timeouts + basic.num_sock_timeouts + basic.num_sock_fdunavail + basic.num_sock_ftabfull + basic.num_sock_refused + basic.num_sock_reset + basic.num_sock_addrunavail + basic.num_sock_addrinuse + basic.num_other_errors), basic.num_client_timeouts, basic.num_sock_timeouts, basic.num_sock_refused, basic.num_sock_reset, basic.num_sock_fdunavail, basic.num_sock_addrunavail, basic.num_sock_ftabfull, basic.num_sock_addrinuse, basic.num_other_errors); printf("Unconnected timeouts %d connected timeouts %d total (%d) client_timeouts %d\n", basic.num_client_unconnected_timeouts, basic.num_client_connected_timeouts, basic.num_client_unconnected_timeouts + basic.num_client_connected_timeouts, basic.num_client_timeouts); printf ("----------\n"); print_errno_info(); if ( param.spec_stats > 0 ) { print_spec_timeouts(); } #if 0 printf ("%6s %6s\n", "errno", "count"); for (i=0; i seconds */ /* have elapsed and ending seconds before the end of the experiment. */ if (param.ramp_up_conns > 0) stable_conns_start = param.ramp_up_conns; else stable_conns_start = -1; if (param.ramp_down_conns > 0) { if (param.wsesslog.num_sessions) { stable_conns_end = param.wsesslog.num_sessions - param.ramp_down_conns; } else { printf("We don't currently handle --ramp-down-conns unless wsesslog is used\n"); exit(1); } } else { stable_conns_end = INT_MAX; } printf( "Stable period is %ld to %ld connections\n", stable_conns_start, stable_conns_end ); } #endif /* UW_STABLE_STATS */ static void init (void) { Any_Type arg; err_report_init(); if( param.spec_stats > 0 ) { spec_stats_init(); } #ifdef UW_CALL_STATS if( param.call_stats >= 0) { call_stats_init(); } #endif /* UW_CALL_STATS */ basic.max_conns = 0; basic.max_connected_conns = 0; basic.num_connected_conns = 0; basic.num_client_connected_timeouts = 0; basic.num_client_unconnected_timeouts = 0; basic.conn_lifetime_min = DBL_MAX; basic.reply_rate_min = DBL_MAX; #ifdef UW_THROUGHPUT_STATS basic.throughput_min = DBL_MAX; #endif /* UW_THROUGHPUT_STATS */ basic.conn_lifetime_sum_notm = 0.0; basic.conn_lifetime_sum_tm = 0.0; basic.timeout_replies = 0; basic.no_timeout_replies = 0; #ifdef UW_STABLE_STATS stable_stats_init(); #endif /* UW_STABLE_STATS */ arg.l = 0; event_register_handler (EV_PERF_SAMPLE, perf_sample, arg); event_register_handler (EV_CONN_FAILED, conn_fail, arg); event_register_handler (EV_CONN_TIMEOUT, conn_timeout, arg); event_register_handler (EV_CONN_NEW, conn_created, arg); event_register_handler (EV_CONN_CONNECTING, conn_connecting, arg); event_register_handler (EV_CONN_CONNECTED, conn_connected, arg); event_register_handler (EV_CONN_CLOSE, conn_close, arg); event_register_handler (EV_CONN_DESTROYED, conn_destroyed, arg); event_register_handler (EV_CALL_SEND_START, send_start, arg); event_register_handler (EV_CALL_SEND_STOP, send_stop, arg); event_register_handler (EV_CALL_RECV_START, recv_start, arg); event_register_handler (EV_CALL_RECV_STOP, recv_stop, arg); event_register_handler (EV_DUMP_STATS, dump_stats, arg); } static void dump (void) { Time conn_period = 0.0, call_period = 0.0; Time conn_time = 0.0, resp_time = 0.0, xfer_time = 0.0; Time call_size = 0.0, hdr_size = 0.0, reply_size = 0.0, footer_size = 0.0; Time lifetime_avg = 0.0, lifetime_stddev = 0.0, lifetime_median = 0.0; double avg = 0.0, stddev = 0.0, reply_rate_overall = 0.0; double response_time = 0.0; int i, total_replies = 0; Time delta, user, sys; u_wide total_size; Time time; u_int n; FILE *fp = NULL; if (NULL == param.output_log) { fp = fopen("output.log", "w"); } else { fp = fopen(param.output_log, "w"); } if (fp == NULL) { fprintf(stderr, "Error: Couldn't write output results!\n"); return; } for (i = 1; i < NELEMS (basic.num_replies); ++i) total_replies += basic.num_replies[i]; #ifdef UW_STABLE_STATS if (stable_conns_start < 0) { if (stable_conns_end > param.wsesslog.num_sessions) delta = test_time_stop - test_time_start; else delta = stable_conns_end * param.rate.mean_iat; } else { if (stable_conns_end > param.wsesslog.num_sessions) { delta = (param.wsesslog.num_sessions - stable_conns_start) * param.rate.mean_iat; } else { delta = (stable_conns_end - stable_conns_start) * param.rate.mean_iat; } } #else delta = test_time_stop - test_time_start; #endif /* UW_STABLE_STATS */ if (verbose > 1) { fprintf (fp,"\nConnection lifetime histogram (time in ms):\n"); for (i = 0; i < NUM_BINS; ++i) if (basic.conn_lifetime_hist[i]) { if (i > 0 && basic.conn_lifetime_hist[i - 1] == 0) fprintf (fp,"%14c\n", ':'); time = (i + 0.5)*BIN_WIDTH; fprintf (fp,"%16.1f %u\n", 1e3*time, basic.conn_lifetime_hist[i]); } } fprintf (fp,"\nTotal: connections %u requests %u replies %u " "test-duration %.3f s\n", basic.num_conns_issued, basic.num_sent, total_replies, delta); fprintf(fp,"Number of connected connections is currently = %d\n", basic.num_connected_conns); if (basic.num_connected_conns != 0) { fprintf(fp,"WARNING: was expecting 0 and got %d\n", basic.num_connected_conns); } fprintf(fp, "\n"); if (basic.num_conns_issued) conn_period = delta/basic.num_conns_issued; fprintf (fp,"Connection rate: %.1f conn/s (%.1f ms/conn, " "<=%u concurrent connections)\n", basic.num_conns_issued / delta, 1e3*conn_period, basic.max_conns); fprintf (fp,"Connected connection rate: %.1f conn/s (%.1f ms/conn, " "<=%d concurrent connected connections)\n", basic.num_total_connected_conns / delta, 1e3*conn_period, basic.max_connected_conns); if (basic.num_lifetimes > 0) { lifetime_avg = (basic.conn_lifetime_sum / basic.num_lifetimes); if (basic.num_lifetimes > 1) lifetime_stddev = STDDEV (basic.conn_lifetime_sum, basic.conn_lifetime_sum2, basic.num_lifetimes); n = 0; for (i = 0; i < NUM_BINS; ++i) { n += basic.conn_lifetime_hist[i]; if (n >= 0.5*basic.num_lifetimes) { lifetime_median = (i + 0.5)*BIN_WIDTH; break; } } } else { lifetime_avg = param.timeout; lifetime_median = param.timeout; } fprintf (fp, "Connection time [ms]: min %.1f avg %.1f max %.1f median %.1f " "stddev %.1f\n", basic.num_lifetimes > 0 ? 1e3 * basic.conn_lifetime_min : 0.0, 1e3 * lifetime_avg, 1e3 * basic.conn_lifetime_max, 1e3 * lifetime_median, 1e3 * lifetime_stddev); if (basic.num_connects > 0) conn_time = basic.conn_connect_sum / basic.num_connects; fprintf (fp, "Connection time [ms]: connect %.1f\n", 1e3*conn_time); fprintf (fp, "Connection length [replies/conn]: %.3f\n", basic.num_lifetimes > 0 ? total_replies/ (double) basic.num_lifetimes : 0.0); fprintf (fp, "\n"); // if( basic.num_lifetimes > 0 ) { // n = basic.timeout_replies + basic.no_timeout_replies; // fprintf(fp, "Number of sessions that eventually timed-out: %d (%.1f %%)\n", basic.timeout_replies, 100.0 * basic.timeout_replies / n); // if(basic.no_timeout_replies > 0 ) // response_time = 1e3 * basic.conn_lifetime_sum_notm / basic.no_timeout_replies; // else // response_time = 0.0; // fprintf(fp, "\n"); fprintf(fp, "Response time (no timeouts) [ms]: %.1f\n", response_time); if(basic.timeout_replies > 0 ) response_time = 1e3 * basic.conn_lifetime_sum_tm / basic.timeout_replies; else response_time = 0.0; fprintf(fp, "Response time (only timeouts) [ms]: %.1f\n", response_time); if( n > 0 ) response_time = 1e3 * (basic.conn_lifetime_sum_tm + basic.conn_lifetime_sum_notm) / n; else response_time = 1e3 * param.timeout; fprintf(fp, "Response time (all) [ms]: %.1f\n", response_time); // } #ifdef UW_STABLE_STATS lifetime_stddev = 0.0; lifetime_median = 0.0; if (basic.all_num_lifetimes > 0) { lifetime_avg = basic.all_lifetime_sum / basic.all_num_lifetimes; if (basic.all_num_lifetimes > 1) lifetime_stddev = STDDEV (basic.all_lifetime_sum, basic.all_lifetime_sum2, basic.all_num_lifetimes); #if 0 n = 0; for (i = 0; i < NUM_BINS; ++i) { n += basic.all_lifetime_hist[i]; if (n >= 0.5*basic.all_num_lifetimes) { lifetime_median = (i + 0.5)*BIN_WIDTH; break; } } #endif } fprintf(fp, "\n"); fprintf (fp, "\nAll: connections %u requests %u replies %u test-duration %.3f s\n", basic.all_conns_issued, basic.num_all_sent, basic.num_all_replies, test_time_stop - test_time_start ); fprintf (fp, "All Conn time [ms]: min %.1f avg %.1f max %.1f median %.1f " "stddev %.1f\n", basic.all_num_lifetimes > 0 ? 1e3 * basic.all_lifetime_min : 0.0, 1e3 * lifetime_avg, 1e3 * basic.all_lifetime_max, 1e3 * lifetime_median, 1e3 * lifetime_stddev); n = basic.all_timeout_replies + basic.all_no_timeout_replies; fprintf(fp, "All Connections timed-out: %d (%.1f %%)\n", basic.all_timeout_replies, 100.0 * basic.all_timeout_replies / n); if( basic.all_no_timeout_replies > 0 ) response_time = 1e3 * basic.all_lifetime_sum_notm / basic.all_no_timeout_replies; else response_time = 0.0; fprintf(fp, "All Resp time (no timeouts) [ms]: %.1f\n", response_time); if(basic.all_timeout_replies > 0 ) response_time = 1e3 * basic.all_lifetime_sum_tm / basic.all_timeout_replies; else response_time = 0.0; fprintf(fp, "All Resp time (only timeouts) [ms]: %.1f\n", response_time); if( n > 0 ) response_time = 1e3 * (basic.all_lifetime_sum_tm + basic.all_lifetime_sum_notm) / n; else response_time = 1e3 * param.timeout; fprintf(fp, "All Resp time (all) [ms]: %.1f\n", response_time); if (basic.num_all_replies) { hdr_size = basic.all_hdr_bytes_received / basic.num_all_replies; reply_size = basic.all_reply_bytes_received / basic.num_all_replies; footer_size = basic.all_footer_bytes_received / basic.num_all_replies; } fprintf (fp, "All Reply size [B]: header %.1f content %.1f footer %.1f " "(total %.1f)\n", hdr_size, reply_size, footer_size, hdr_size + reply_size + footer_size); putchar ('\n'); #endif /* UW_STABLE_STATS */ if (basic.num_sent > 0) call_period = delta/basic.num_sent; fprintf (fp, "Request rate: %.1f req/s (%.1f ms/req)\n", basic.num_sent / delta, 1e3*call_period); if (basic.num_sent) call_size = basic.req_bytes_sent / basic.num_sent; fprintf (fp, "Request size [B]: %.1f\n", call_size); fprintf (fp, "\n"); reply_rate_overall = ((double) total_replies) / delta; fprintf(fp, "Overall reply rate: %.1f replies/sec\n",reply_rate_overall); if (basic.num_reply_samples > 0) { avg = (basic.reply_rate_sum / basic.num_reply_samples); if (basic.num_reply_samples > 1) stddev = STDDEV (basic.reply_rate_sum, basic.reply_rate_sum2, basic.num_reply_samples); } fprintf (fp, "Reply rate [replies/s]: min %.1f avg %.1f max %.1f stddev %.1f " "(%u samples)\n", basic.num_reply_samples > 0 ? basic.reply_rate_min : 0.0, avg, basic.reply_rate_max, stddev, basic.num_reply_samples); #ifdef UW_THROUGHPUT_STATS avg = 0.0; stddev = 0.0; if (basic.num_reply_samples > 0) { avg = (basic.throughput_sum / basic.num_reply_samples); if (basic.num_reply_samples > 1) stddev = STDDEV (basic.throughput_sum, basic.throughput_sum2, basic.num_reply_samples); } fprintf (fp, "Throughput [Mbps]: min %.2f avg %.2f max %.2f stddev %.2f " "(%u samples)\n", basic.num_reply_samples > 0 ? basic.throughput_min : 0.0, avg, basic.throughput_max, stddev, basic.num_reply_samples); #endif /* UW_THROUGHPUT_STATS */ if (basic.num_responses > 0) resp_time = basic.call_response_sum / basic.num_responses; if (total_replies > 0) xfer_time = basic.call_xfer_sum / total_replies; else { /* if no responses, asssume transfer time is the timeout period */ xfer_time = param.timeout; } fprintf (fp, "Reply time [ms]: response %.1f transfer %.1f\n", 1e3*resp_time, 1e3*xfer_time); if (total_replies) { hdr_size = basic.hdr_bytes_received / total_replies; reply_size = basic.reply_bytes_received / total_replies; footer_size = basic.footer_bytes_received / total_replies; } fprintf (fp, "Reply size [B]: header %.1f content %.1f footer %.1f " "(total %.1f)\n", hdr_size, reply_size, footer_size, hdr_size + reply_size + footer_size); fprintf (fp, "Reply status: 1xx=%u 2xx=%u 3xx=%u 4xx=%u 5xx=%u\n", basic.num_replies[1], basic.num_replies[2], basic.num_replies[3], basic.num_replies[4], basic.num_replies[5]); fprintf(fp, "\n"); user = (TV_TO_SEC (test_rusage_stop.ru_utime) - TV_TO_SEC (test_rusage_start.ru_utime)); sys = (TV_TO_SEC (test_rusage_stop.ru_stime) - TV_TO_SEC (test_rusage_start.ru_stime)); fprintf (fp, "CPU time [s]: user %.2f system %.2f (user %.1f%% system %.1f%% " "total %.1f%%)\n", user, sys, 100.0*user/delta, 100.0*sys/delta, 100.0*(user + sys)/delta); total_size = (basic.req_bytes_sent + basic.hdr_bytes_received + basic.reply_bytes_received); fprintf (fp, "Net I/O: %.1f KB/s (%.1f*10^6 bps)\n", total_size/delta / 1024.0, 8e-6*total_size/delta); fprintf (fp, "\n"); fprintf (fp, "Errors: total %u client-timo %u socket-timo %u " "connrefused %u connreset %u\n" "Errors: fd-unavail %u addrunavail %u ftab-full %u " "addrinuse %u other %u\n", (basic.num_client_timeouts + basic.num_sock_timeouts + basic.num_sock_fdunavail + basic.num_sock_ftabfull + basic.num_sock_refused + basic.num_sock_reset + basic.num_sock_addrunavail + basic.num_sock_addrinuse + basic.num_other_errors), basic.num_client_timeouts, basic.num_sock_timeouts, basic.num_sock_refused, basic.num_sock_reset, basic.num_sock_fdunavail, basic.num_sock_addrunavail, basic.num_sock_ftabfull, basic.num_sock_addrinuse, basic.num_other_errors); fprintf(fp, "Unconnected timeouts %d connected timeouts %d total (%d) client_timeouts %d\n", basic.num_client_unconnected_timeouts, basic.num_client_connected_timeouts, basic.num_client_unconnected_timeouts + basic.num_client_connected_timeouts, basic.num_client_timeouts); print_errno_info(); if( param.spec_stats > 0 ) { print_spec_timeouts(); } #ifdef UW_CALL_STATS if( param.call_stats > 0){ print_call_stats(); } #endif /* UW_CALL_STATS */ fprintf(fp, "\n"); fclose(fp); } Stat_Collector stats_basic = { "Basic statistics", init, no_op, no_op, dump }; void print_errno_info() { int i; int count; count = 0; for (i=0; i 0) { printf("Tracked errnos\n"); printf("%6s %6s %s\n", "errno", "count", "Error string"); for (i=0; i 0) { printf("\nTracked internal httperf errors\n"); printf ("%6s %6s %s\n", "Error", "count", "Message"); for (i=0; i<(CONN_ERR_COUNT); i++) { /* printf("i = %d count = %d\n", i, httperf_errs_reported[i]); */ if (httperf_errs_reported[i]) { printf("%6d %6d ", -i, httperf_errs_reported[i]); switch(-i) { case CONN_ERR_NOT_SET: printf("connection failed but error value wasn't set properly\n"); break; case CONN_ERR_NO_MORE_PORTS: printf("connection failed because no ports were available\n"); break; case CONN_ERR_HASH_LOOKUP_FAILED: printf("connection failed because hash_lookup failed\n"); break; case CONN_ERR_STATE_PAST_CLOSING: printf("connection failed because of incorrect state\n"); break; default: printf("no message for this type of error\n"); break; } } } } } #ifdef LOCAL_DEBUG void print_connected_info(char *func, int sd, int state) { ldbg("%15s: sd = %5d state = %2d num_connected_conns = %8d " "max_connected_conns %8d", func, sd, state, basic.num_connected_conns, basic.max_connected_conns); if (state >= S_CONNECTED && sd > 0) { ldbg(" (was connected)\n"); } else { ldbg(" (was not connected)\n"); } } #endif ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/stat/call_stats.c ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* This stats module was added to allow httperf to gather statistics on a per call basis. Author: Tyler Szepesi Date: August, 2010 */ #ifdef UW_CALL_STATS #include "call_stats.h" #include #include #include #include #include #include #include #define URI_SIZE 80 /* Maximum size allowed for a URI for a given call */ /* --call-stats=buf_size * indicates max number of calls tracked by call_stats */ int buf_size = 0; /* struct used to gather per call statistics */ typedef struct { char c_name[URI_SIZE]; /* file name */ u_long c_call_id; /* call id */ u_long c_conn_id; /* connection id */ int c_size; /* file size */ int c_bytes_recvd; /* bytes received */ double c_perc_recvd; /* percentage of bytes received */ double c_byte_rate; /* rate of receiving bytes */ double c_conn_time; /* time to connect */ double c_resp_time; /* time to receive */ double c_total_time; /*total time */ double c_time_lim; /* time limit */ int c_timeout; /* timed out? */ int c_status; /* HTTP status */ } call_data; call_data *call_stats; /* struct used to format the display of call statistics */ struct print_stats { char *hdr; /* header */ char *units; /* units for data */ char *hdr_frmt; /* format used for header and units*/ char *data_frmt;/* format used for data, should be the same width as above */ char *data_blank; /* used for printing a blank data entry, use with hdr_frmt */ }; struct print_stats print_info[]={ {"call number", "", "%-13s", "%-13d", ""}, {"conn number", "", "%-13s", "%-13d", ""}, {"request size", "(bytes)", "%-14s", "%-14d", ""}, {"response size", "(bytes)", "%-15s", "%-15d", ""}, {"% bytes recvd", "", "%-15s", "%-15.2f", ""}, {"byte rate", "(Mbps)", "%-11s", "%-11.1f", ""}, {"conn time", "(s)", "%-11s", "%-11.7f", ""}, {"response time", "(s)", "%-15s", "%-15.7f", ""}, {"total time", "(s)", "%-12s", "%-12.7f", ""}, {"HTTP status", "", "%-13s", "%-13d", ""}, {"time limit", "(s)", "%-11s", "%-11.7f", ""}, {"timed out", "", "%-11s", "%-11s", ""}, {"file requested", "", "%s", "%s", ""}, {0,0,0,0,0} }; /* number of call_stats lines printed */ int print_count = 0; /* struct used to map URIs to file sizes */ struct f_uri_size { char f_uri[URI_SIZE]; int f_size; }; struct f_uri_size *f_sizes; struct f_uri_size *prev_f = NULL; int num_files; /* this function is used to construct the (URI, file size) mapping */ void build_fsize () { int size; int i; char buf[URI_SIZE]; FILE *fd; int er; /* open the file */ fd = fopen (param.call_stats_file, "r"); if (fd == NULL) { fprintf(stderr, "unable to open the call_stats file: %s\n", param.call_stats_file); exit (1); } /* get the number of entries */ er = fscanf (fd, "%d\n", &num_files); if (er < 1) { fprintf (stderr, "first line of call_stats file not a number\n"); exit(1); } /* malloc the f_sizes array */ f_sizes = malloc (sizeof (struct f_uri_size)*num_files); if (f_sizes == NULL) { fprintf(stderr, "malloc failed to allocate f_sizes array\n"); exit (1); } /* fill in the f_sizes array */ for (i = 0; i < num_files; i++) { /* read line */ er = fscanf(fd, "%s %d\n", buf, &size); if (er < 2) { fprintf (stderr, "Line %d of call_stats file is not properly formated\n", i+2); exit(1); } /* populate entry in f_sizes array */ strncpy (f_sizes[i].f_uri, buf, URI_SIZE); f_sizes[i].f_size = size; } /* close the file */ fclose(fd); } /* this function is used to determine the size of a file based on its URI */ int get_f_size (char uri[URI_SIZE]) { int i; int match; if (strncmp (uri, "--", 2) == 0) { return -1; } /* Check if this is the same as the previous file looked up */ if (prev_f != NULL) { if (strncmp(uri, prev_f->f_uri, URI_SIZE) == 0) { return prev_f->f_size; } } /* look up file in pre-constructed table */ for (i = 0; i < num_files; i++) { match = strncmp (uri, f_sizes[i].f_uri, URI_SIZE); if (match == 0) { prev_f = &f_sizes[i]; return f_sizes[i].f_size; } } return -2; } /* Print stats header info */ void print_header_line() { int i = 0; /* print column headers */ while (print_info[i].hdr != 0) { printf(print_info[i].hdr_frmt, print_info[i].hdr); i++; } printf("\n"); i = 0; /* print column units */ while (print_info[i].hdr != 0) { printf(print_info[i].hdr_frmt, print_info[i].units); i++; } printf("\n"); } /* Print the stats for one call */ void print_call (call_data cd) { /* reprint the header every 20 lines */ if (print_count == 0) { print_header_line(); } print_count++; if (print_count == 20) { print_count = 0; } /* convert timeout id to string */ char * timeout = "yes-NC"; int i = 0; if (cd.c_timeout == 1) { timeout = "yes-C"; } else if (cd.c_timeout == 2) { timeout = "yes-NC"; } else if (cd.c_timeout == -1) { timeout = "NA"; } else { timeout = "no"; } /* print out a row of stats * one row = one call */ if (cd.c_call_id != -1) { printf(print_info[i].data_frmt, cd.c_call_id); } else { printf(print_info[i].hdr_frmt, print_info[i].data_blank); } i++; if (cd.c_conn_id != -1) { printf(print_info[i].data_frmt, cd.c_conn_id); } else { printf(print_info[i].hdr_frmt, print_info[i].data_blank); } i++; if (cd.c_size != -1) { printf(print_info[i].data_frmt, cd.c_size); } else { printf(print_info[i].hdr_frmt, print_info[i].data_blank); } i++; if (cd.c_bytes_recvd != -1) { printf(print_info[i].data_frmt, cd.c_bytes_recvd); } else { printf(print_info[i].hdr_frmt, print_info[i].data_blank); } i++; if (cd.c_perc_recvd != -1) { printf(print_info[i].data_frmt, cd.c_perc_recvd); } else { printf(print_info[i].hdr_frmt, print_info[i].data_blank); } i++; if (cd.c_byte_rate != -1) { printf(print_info[i].data_frmt, cd.c_byte_rate); } else { printf(print_info[i].hdr_frmt, print_info[i].data_blank); } i++; if (cd.c_conn_time != -1) { printf(print_info[i].data_frmt, cd.c_conn_time); } else { printf(print_info[i].hdr_frmt, print_info[i].data_blank); } i++; if (cd.c_resp_time != -1) { printf(print_info[i].data_frmt, cd.c_resp_time); } else { printf(print_info[i].hdr_frmt, print_info[i].data_blank); } i++; if (cd.c_total_time != -1) { printf(print_info[i].data_frmt, cd.c_total_time); } else { printf(print_info[i].hdr_frmt, print_info[i].data_blank); } i++; if (cd.c_status != -1) { printf(print_info[i].data_frmt, cd.c_status); } else { printf(print_info[i].hdr_frmt, print_info[i].data_blank); } i++; if (cd.c_time_lim != -1) { printf(print_info[i].data_frmt, cd.c_time_lim); } else { printf(print_info[i].hdr_frmt, print_info[i].data_blank); } i++; printf(print_info[i++].data_frmt, timeout); printf(print_info[i++].data_frmt, cd.c_name); printf("\n"); } /* Initialize the data structures used for tracking per call statistics */ void call_stats_init() { int i; buf_size = param.call_stats; call_stats = malloc (sizeof(call_data)*buf_size); if (call_stats == NULL) { fprintf(stderr, "malloc failed to allocate call_stats array\n"); exit (1); } if (strncmp (param.call_stats_file, "", 1) != 0) { build_fsize(); } for (i = 0; i < buf_size; i++) { strcpy(call_stats[i].c_name, "--"); call_stats[i].c_conn_id = -1; call_stats[i].c_call_id = -1; call_stats[i].c_size = -1; call_stats[i].c_bytes_recvd = -1; call_stats[i].c_perc_recvd = -1; call_stats[i].c_byte_rate = -1; call_stats[i].c_conn_time = -1; call_stats[i].c_resp_time = -1; call_stats[i].c_total_time = -1; call_stats[i].c_time_lim = -1; call_stats[i].c_timeout = -1; call_stats[i].c_status = -1; } } /* this function is used to get the index into the call_stats array based * on the call*/ int get_index (Call * c) { int index = c->id; assert (index >= 0); if (index >= buf_size) { index = -1; } return index; } /* This function is called once a request has been sent to the server*/ void track_call_request(Call *c ) { assert (c != NULL); assert (c->conn != NULL); if (c->conn->basic.num_calls_completed == 0) { c->record_conn_time = 1; } int index = get_index(c); if (index != -1) { strncpy (call_stats[index].c_name, (char *) c->req.iov[IE_URI].iov_base, URI_SIZE); call_stats[index].c_conn_id = c->conn->id; call_stats[index].c_call_id = c->id; #ifdef UW_DYNOUT if (c->timelimit != 0) { call_stats[index].c_time_lim = c->timelimit; } else { call_stats[index].c_time_lim = param.timeout; } #else call_stats[index].c_time_lim = param.timeout; #endif /* UW_DYNOUT */ if (param.num_sessions) { call_stats[index].c_size = c->file_size; } else if (strncmp (param.uri, "/", 2) != 0) { call_stats[index].c_size = get_f_size(call_stats[index].c_name); } else { call_stats[index].c_size = -2; } /* if this is the first call for a connection * it is responsible for the connection time */ /* ASSUMPTION: this only works if the second call waits for the * first call to be completed before sending its request */ if (c->conn->basic.num_calls_completed == 0) { call_stats[index].c_conn_time = c->conn->basic.time_to_connect; } else { call_stats[index].c_conn_time = 0; } } } /* This function is called once the first byte of a reply is received from the server. */ void track_call_response(Call * c, double response_start_time) { } /* This function is called when the last byte of a reply is received from the server */ void track_call_reply(Call * c, double transfer_time) { assert (c != NULL); /* print information on the fly */ if (param.call_stats == 0) { call_data cd; cd.c_call_id = c->id; cd.c_conn_id = c->conn->id; strncpy (cd.c_name, (char *) c->req.iov[IE_URI].iov_base, URI_SIZE); cd.c_size =c->file_size ; if (param.num_sessions) { cd.c_size = c->file_size; } else if (strncmp (param.uri, "/", 2) != 0) { cd.c_size = get_f_size(cd.c_name); } else { cd.c_size = -2; } cd.c_bytes_recvd = (int) c->reply.content_bytes; cd.c_status =c->reply.status ; #ifdef UW_DYNOUT if (c->timelimit != 0) { cd.c_time_lim = c->timelimit; } else { cd.c_time_lim = param.timeout; } #else cd.c_time_lim =param.timeout ; #endif /* UW_DYNOUT */ cd.c_timeout = 0; cd.c_conn_time = c->record_conn_time == 1 ? c->conn->basic.time_to_connect : 0; cd.c_resp_time = transfer_time + c->basic.time_recv_start - c->basic.time_send_start; cd.c_total_time = cd.c_conn_time + cd.c_resp_time; cd.c_byte_rate = (double) ((double) c->reply.content_bytes / (double) cd.c_resp_time) * 8.0 / 1000000.0; cd.c_perc_recvd = 100 * ((double) c->reply.content_bytes / (double) cd.c_size); print_call(cd); } else { int index = get_index(c); if (index != -1) { call_stats[index].c_timeout = 0; call_stats[index].c_resp_time = transfer_time + c->basic.time_recv_start - c->basic.time_send_start; call_stats[index].c_total_time = call_stats[index].c_resp_time + call_stats[index].c_conn_time; call_stats[index].c_status = c->reply.status; call_stats[index].c_bytes_recvd = (int) c->reply.content_bytes; call_stats[index].c_perc_recvd = 100 * ((double) call_stats[index].c_bytes_recvd / (double) call_stats[index].c_size); call_stats[index].c_byte_rate = (double) ((double) call_stats[index].c_bytes_recvd / (double) call_stats[index].c_resp_time) * 8.0 / 1000000.0; } } } /* This function is called when a connection times out. */ void process_call_timeout(Conn * c ) { assert (c != NULL); Call * cur_call; int index; int timeout_type = 1; int i = 0; /* process calls in the connection's send queue * The send queue holds all calls that are waiting * have their requests sent to the web server */ cur_call = c->sendq; while (cur_call != NULL) { /* print information on the fly */ if (param.call_stats == 0) { call_data cd; cd.c_call_id = cur_call->id; cd.c_conn_id = cur_call->conn->id; strncpy (cd.c_name, (char *) cur_call->req.iov[IE_URI].iov_base, URI_SIZE); if (param.num_sessions) { cd.c_size = cur_call->file_size; } else if (strncmp (param.uri, "/", 2) != 0) { cd.c_size = get_f_size(cd.c_name); } else { cd.c_size = -2; } #ifdef UW_DYNOUT if (cur_call->timelimit != 0) { cd.c_time_lim = cur_call->timelimit; } else { cd.c_time_lim = param.timeout; } #else cd.c_time_lim = param.timeout; #endif /* UW_DYNOUT */ cd.c_timeout = timeout_type; cd.c_conn_time = -1; cd.c_resp_time = -1; cd.c_total_time = -1; cd.c_byte_rate = -1; cd.c_perc_recvd = -1; cd.c_status = -1; cd.c_bytes_recvd = -1; print_call(cd); } else { index = get_index(cur_call); if (index != -1) { call_stats[index].c_timeout = timeout_type; call_stats[index].c_call_id = index; strncpy (call_stats[index].c_name, (char *) cur_call->req.iov[IE_URI].iov_base, URI_SIZE); if (param.num_sessions) { call_stats[index].c_size = cur_call->file_size; } else if (strncmp (param.uri, "/", 2) != 0) { call_stats[index].c_size = get_f_size(call_stats[index].c_name); } else { call_stats[index].c_size = -2; } call_stats[index].c_conn_id = c->id; #ifdef UW_DYNOUT if (cur_call->timelimit != 0) { call_stats[index].c_time_lim = cur_call->timelimit; } else { call_stats[index].c_time_lim = param.timeout; } #else call_stats[index].c_time_lim = param.timeout; #endif /* UW_DYNOUT */ } } cur_call = cur_call->sendq_next; } /* process calls in the connection's receive queue * The receive queue holds all call that are waiting * for a response from the web server */ cur_call = c->recvq; while (cur_call != NULL) { /* print information on the fly */ if (param.call_stats == 0) { call_data cd; cd.c_call_id = cur_call->id; cd.c_conn_id = cur_call->conn->id; strncpy (cd.c_name, (char *) cur_call->req.iov[IE_URI].iov_base, URI_SIZE); if (param.num_sessions) { cd.c_size = cur_call->file_size; } else if (strncmp (param.uri, "/", 2) != 0) { cd.c_size = get_f_size(cd.c_name); } else { cd.c_size = -2; } cd.c_bytes_recvd = (int) cur_call->reply.content_bytes; cd.c_status = cur_call->reply.status ; #ifdef UW_DYNOUT if (cur_call->timelimit != 0) { cd.c_time_lim = cur_call->timelimit; } else { cd.c_time_lim = param.timeout; } #else cd.c_time_lim = param.timeout; #endif /* UW_DYNOUT */ cd.c_timeout = timeout_type; cd.c_conn_time = cur_call->record_conn_time == 1 ? cur_call->conn->basic.time_to_connect : 0; cd.c_resp_time = c->basic.time_of_timeout - cur_call->basic.time_send_start; cd.c_total_time = cd.c_conn_time + cd.c_resp_time; cd.c_byte_rate = (double) ((double) cur_call->reply.content_bytes / (double) cd.c_resp_time) * 8.0 / 1000000.0; cd.c_perc_recvd = 100 * ((double) cur_call->reply.content_bytes / (double) cd.c_size); print_call(cd); } else { index = get_index(cur_call); if (index != -1) { call_stats[index].c_timeout = timeout_type; call_stats[index].c_status = cur_call->reply.status; call_stats[index].c_bytes_recvd = (int) cur_call->reply.content_bytes; call_stats[index].c_resp_time = c->basic.time_of_timeout - cur_call->basic.time_send_start; call_stats[index].c_total_time = call_stats[index].c_resp_time + call_stats[index].c_conn_time; call_stats[index].c_perc_recvd = 100 * (double) cur_call->reply.content_bytes / (double) call_stats[index].c_size; call_stats[index].c_byte_rate = (double) ((double) cur_call->reply.content_bytes / (double) call_stats[index].c_resp_time) * 8.0 / 1000000.0; } } cur_call = cur_call->recvq_next; } /* Simulate the calls that never happened by * not allowing the id that they should have used * to be used by another call */ int calls; /* this is used if a session log file generated the requests */ if (param.num_sessions) { calls = num_missed_calls(c); set_missed_calls(c); } else if (strncmp (param.uri, "/", 2) != 0) { /* this is used if a videosesslog file was not specified */ if (c->state < S_CONNECTED) { timeout_type = 2; calls = param.num_calls - c->basic.num_calls_completed; } else { /* Don't count the call that timed out, as it has already been * taken care of above */ calls = param.num_calls - c->basic.num_calls_completed - 1; } } else { /* No other load generating mechanism is currently supported */ calls = 0; } /* if this connection timed out before it was connected * then the first call was already created when using videosesslog*/ if (c->state < S_CONNECTED && param.num_sessions) { cur_call = session_get_last_call(c); timeout_type = 2; /* print information on the fly */ if (param.call_stats == 0) { call_data cd; cd.c_call_id = cur_call->id; cd.c_conn_id = c->id; strncpy (cd.c_name, (char *) cur_call->req.iov[IE_URI].iov_base, URI_SIZE); if (param.num_sessions) { cd.c_size = cur_call->file_size; } else if (strncmp (param.uri, "/", 2) != 0) { cd.c_size = get_f_size(cd.c_name); } else { cd.c_size = -2; } #ifdef UW_DYNOUT if (cur_call->timelimit != 0) { cd.c_time_lim = cur_call->timelimit; } else { cd.c_time_lim = param.timeout; } #else cd.c_time_lim = param.timeout; #endif /* UW_DYNOUT */ cd.c_timeout = timeout_type; cd.c_conn_time = c->basic.time_of_timeout - c->basic.time_connect_start; cd.c_resp_time = -1; cd.c_total_time = -1; cd.c_byte_rate = -1; cd.c_perc_recvd = -1; cd.c_status = -1; cd.c_bytes_recvd = -1; print_call(cd); } else { index = get_index(cur_call); if (index != -1) { call_stats[index].c_timeout = timeout_type; strncpy (call_stats[index].c_name, (char *) cur_call->req.iov[IE_URI].iov_base, URI_SIZE); if (param.num_sessions) { call_stats[index].c_size = cur_call->file_size; } else if (strncmp (param.uri, "/", 2) != 0) { call_stats[index].c_size = get_f_size(call_stats[index].c_name); } else { call_stats[index].c_size = -2; } call_stats[index].c_conn_id = c->id; call_stats[index].c_call_id = index; call_stats[index].c_conn_time = c->basic.time_of_timeout - c->basic.time_connect_start; #ifdef UW_DYNOUT if (cur_call->timelimit != 0) { call_stats[index].c_time_lim = cur_call->timelimit; } else { call_stats[index].c_time_lim = param.timeout; } #else call_stats[index].c_time_lim = param.timeout; #endif /* UW_DYNOUT */ } calls--; } } if (calls > 0) { inc_call_next_id(calls); int top = get_call_next_id (); i = top - calls; if (top > buf_size && param.call_stats != 0) { top = buf_size; } for (; i < top; i++) { /* print information on the fly */ if (param.call_stats == 0) { call_data cd; cd.c_call_id = i; cd.c_conn_id = c->id; if (param.num_sessions) { strncpy (cd.c_name, get_next_missed_uri(c), URI_SIZE); cd.c_size = get_next_missed_size(c); } else if (strncmp (param.uri, "/", 2) != 0) { strncpy (cd.c_name, param.uri, URI_SIZE); cd.c_size = get_f_size(cd.c_name); } else { strcpy(cd.c_name, "--"); cd.c_size = -2; } #ifdef UW_DYNOUT cd.c_time_lim = get_next_missed_timelimit(c); #else cd.c_time_lim = param.timeout; #endif /* UW_DYNOUT */ cd.c_timeout = timeout_type; cd.c_conn_time = -1; cd.c_resp_time = -1; cd.c_total_time = -1; cd.c_byte_rate = -1; cd.c_perc_recvd = -1; cd.c_status = -1; cd.c_bytes_recvd = -1; print_call(cd); } else { call_stats[i].c_call_id= i; call_stats[i].c_conn_id = c->id; call_stats[i].c_timeout = timeout_type; if (param.num_sessions) { //strncpy (call_stats[i].c_name, get_next_missed_uri(c), URI_SIZE); strncpy (call_stats[i].c_name, "BLA", 4); //call_stats[i].c_size = get_next_missed_size(c); call_stats[i].c_size = 0; } else if (strncmp (param.uri, "/", 2) != 0) { strncpy (call_stats[i].c_name, param.uri, URI_SIZE); call_stats[i].c_size = get_f_size(call_stats[i].c_name); } else { strcpy(call_stats[i].c_name, "--"); call_stats[i].c_size = -2; } #ifdef UW_DYNOUT //call_stats[i].c_time_lim = get_next_missed_timelimit(c); call_stats[i].c_time_lim = param.timeout; #else call_stats[i].c_time_lim = param.timeout; #endif /* UW_DYNOUT */ } } } } /* Print a summary of the per call statistics. */ void print_call_stats() { int j=0; int top = 0; top = get_call_next_id(); if (top >= buf_size) { top = buf_size; printf("\nCall Statistics (buffer filled):\n\n"); } else { printf("\nCall Statistics:\n\n"); } /* print data */ for (j = 0; j < top; j++) { print_call(call_stats[j]); } } #ifdef UW_PACE_REQUESTS /* return the total connection time for a call. Returns 0.0 if not available */ double get_call_total_conn_time( Call *cur_call ) { int index = get_index(cur_call); if (index != -1) return( call_stats[index].c_total_time ); else return( 0.0 ); } #endif /* UW_PACE_REQUESTS */ #endif /* UW_CALL_STATS */ ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/stat/call_stats.h ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _CALL_STATS_H_ #define _CALL_STATS_H_ #ifdef UW_CALL_STATS #include #include /* Initialize the data structures used for tracking per file statistics */ void call_stats_init(); /* This function is called once a request has been sent to the server*/ void track_call_request(Call *c); /* This function is called once the first byte of a reply is received from the server. */ void track_call_response(Call * c, double response_start_time); /* This function is called when the last byte of a reply is received from the server */ void track_call_reply(Call * c, double transfer_time); /* This function is called when a connection times out. */ void process_call_timeout(Conn * c ); /* Print a summary of the per file statistics. */ void print_call_stats(); #endif /* UW_CALL_STATS */ #endif /* _CALL_STATS_H_ */ ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/stat/print_reply.c ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* This statistics collector simply prints the replies received from the server. */ #include #include #include #include #include #include #include #include typedef struct Call_Private_Data { int done_with_reply_hdr; /* are we done printing reply header? */ size_t size; /* number of bytes allocated for "line" buffer */ size_t len; /* current length of line buffer */ char *line; /* line buffer */ } Call_Private_Data; #define CALL_PRIVATE_DATA(c) \ ((Call_Private_Data *) ((char *)(c) + call_private_data_offset)) static size_t call_private_data_offset = -1; static void flush_print_buf (Call *call, const char *prefix) { Call_Private_Data *priv = CALL_PRIVATE_DATA (call); if (priv->len) printf ("%s%ld:%.*s\n", prefix, call->id, (int) priv->len, priv->line); priv->len = 0; } static void print_buf (Call *call, const char *prefix, const char *buf, int len) { Call_Private_Data *priv = CALL_PRIVATE_DATA (call); const char *eol, *end; size_t line_len; for (end = buf + len; buf < end; buf += line_len) { line_len = (end - buf); eol = strchr (buf, '\n'); if (eol) { /* got a complete line: print it */ line_len = eol - buf; printf ("%s%ld:", prefix, call->id); if (priv->len) printf ("%.*s", (int) priv->len, priv->line); priv->len = 0; if (line_len > 0) printf ("%.*s", (int) line_len, buf); putchar ('\n'); ++line_len; /* skip over newline */ } else { /* got a partial line: buffer it */ if (priv->len + line_len > priv->size) { priv->size = priv->len + line_len; if (priv->line) priv->line = realloc (priv->line, priv->size); else priv->line = malloc (priv->size); if (!priv->line) { fprintf (stderr, "%s.print_buf: Out of memory\n", prog_name); exit (1); } } memcpy (priv->line + priv->len, buf, line_len); priv->len += line_len; } } } static void print_request (Call *call) { size_t hdr_len, h_len, b_len; int i, first, end; char *hdr; first = IE_CONTENT; end = IE_CONTENT; if ((param.print_request & PRINT_HEADER) != 0) first = IE_METHOD; if ((param.print_request & PRINT_BODY) != 0) end = IE_LEN; for (i = first; i < end; ++i) { hdr = call->req.iov[i].iov_base; hdr_len = call->req.iov[i].iov_len; if (hdr_len) print_buf (call, (i < IE_CONTENT) ? "SH" : "SB", hdr, hdr_len); } for (h_len = 0, i = IE_METHOD; i < IE_CONTENT; ++i) h_len += call->req.iov[i].iov_len; for (b_len = 0, i = IE_CONTENT; i < IE_LEN; ++i) b_len += call->req.iov[i].iov_len; printf ("SS%ld: header %ld content %ld\n", call->id, (long) h_len, (long) b_len); } static void print_reply_hdr (Call *call, const char *buf, int len) { Call_Private_Data *priv = CALL_PRIVATE_DATA (call); const char *eoh; if (len <= 0 || priv->done_with_reply_hdr) return; eoh = strstr (buf, "\r\n\r\n"); if (eoh) { priv->done_with_reply_hdr = 1; eoh += 4; } else { /* no CRLFCRLF: non-conforming server */ eoh = strstr (buf, "\n\n"); if (eoh) { priv->done_with_reply_hdr = 1; eoh += 2; } else eoh = buf + len; } print_buf (call, "RH", buf, eoh - buf); } static void call_destroyed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { Call_Private_Data *priv; Call *call; assert (et == EV_CALL_DESTROYED && object_is_call (obj)); call = (Call *) obj; priv = CALL_PRIVATE_DATA (call); if (priv->line) free (priv->line); } static void send_raw_data (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { Call *call; assert (et == EV_CALL_SEND_RAW_DATA && object_is_call (obj)); call = (Call *) obj; print_request (call); } static void recv_raw_data (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { struct iovec *iov; Call *call; assert (et == EV_CALL_RECV_RAW_DATA && object_is_call (obj)); call = (Call *) obj; iov = callarg.vp; print_reply_hdr (call, iov->iov_base, iov->iov_len); } static void recv_data (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { struct iovec *iov; Call *call; assert (et == EV_CALL_RECV_DATA && object_is_call (obj)); call = (Call *) obj; iov = callarg.vp; print_buf (call, "RB", iov->iov_base, iov->iov_len); } static void recv_stop (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { Call *call; assert (et == EV_CALL_RECV_STOP && object_is_call (obj)); call = (Call *) obj; flush_print_buf (call, "RB"); printf ("RS%ld: header %ld content %ld footer %ld\n", call->id, (long) call->reply.header_bytes, (long) call->reply.content_bytes, (long) call->reply.footer_bytes); } static void init (void) { Any_Type arg; call_private_data_offset = object_expand (OBJ_CALL, sizeof (Call_Private_Data)); arg.l = 0; if ((param.print_request & (PRINT_HEADER | PRINT_BODY)) != 0) event_register_handler (EV_CALL_SEND_RAW_DATA, send_raw_data, arg); if ((param.print_reply & PRINT_HEADER) != 0) event_register_handler (EV_CALL_RECV_RAW_DATA, recv_raw_data, arg); if ((param.print_reply & PRINT_BODY) != 0) event_register_handler (EV_CALL_RECV_DATA, recv_data, arg); if ((param.print_reply & (PRINT_HEADER | PRINT_BODY)) != 0) event_register_handler (EV_CALL_RECV_STOP, recv_stop, arg); event_register_handler (EV_CALL_DESTROYED, call_destroyed, arg); } Stat_Collector stats_print_reply = { "Reply printer", init, no_op, no_op, no_op }; ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/stat/sess_stat.c ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Session statistics collector. */ #include #include #include #include #include #include #include #include #include #include static struct { u_int num_rate_samples; u_int num_completed_since_last_sample; Time rate_sum; Time rate_sum2; Time rate_min; Time rate_max; u_int num_completed; Time lifetime_sum; u_int num_failed; Time failtime_sum; u_int num_conns; /* total # of connections on successful sessions */ /* session-length histogram: */ u_int longest_session; u_int len_hist_alloced; u_int *len_hist; } st; #define SESS_PRIVATE_DATA(c) \ ((Sess_Private_Data *) ((char *)(c) + sess_private_data_offset)) typedef struct Sess_Private_Data { u_int num_calls_completed; /* how many calls completed? */ u_int num_conns; /* # of connections on this session */ Time birth_time; /* when this session got created */ } Sess_Private_Data; static size_t sess_private_data_offset = -1; static void perf_sample (Event_Type et, Object *obj, Any_Type reg_arg, Any_Type call_arg) { Time weight = call_arg.d; double rate; assert (et == EV_PERF_SAMPLE); rate = weight*st.num_completed_since_last_sample; st.num_completed_since_last_sample = 0; // aansaarii if(verbose){ printf ("session-rate = %-8.1f (sess/s), session-completed: %-8u, session-failed: %-8u, session-total: %-8u\n", rate, st.num_completed, st.num_failed, st.num_completed + st.num_failed); } ++st.num_rate_samples; st.rate_sum += rate; st.rate_sum2 += SQUARE (rate); if (rate < st.rate_min) st.rate_min = rate; if (rate > st.rate_max) st.rate_max = rate; } static void sess_created (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { Sess_Private_Data *priv; Sess *sess; assert (et == EV_SESS_NEW && object_is_sess (obj)); sess = (Sess *) obj; priv = SESS_PRIVATE_DATA (sess); priv->birth_time = timer_now (); } static void sess_destroyed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { size_t old_size, new_size; Sess_Private_Data *priv; Sess *sess; Time delta, now = timer_now (); assert (et == EV_SESS_DESTROYED && object_is_sess (obj)); sess = (Sess *) obj; priv = SESS_PRIVATE_DATA (sess); delta = (now - priv->birth_time); if (sess->failed) { ++st.num_failed; st.failtime_sum += delta; } else { st.num_conns += priv->num_conns; ++st.num_completed_since_last_sample; ++st.num_completed; st.lifetime_sum += delta; } if (priv->num_calls_completed > st.longest_session) { st.longest_session = priv->num_calls_completed; if (st.longest_session >= st.len_hist_alloced) { old_size = st.len_hist_alloced*sizeof (st.len_hist[0]); st.len_hist_alloced = st.longest_session + 16; new_size = st.len_hist_alloced*sizeof (st.len_hist[0]); st.len_hist = realloc (st.len_hist, new_size); if (!st.len_hist) { fprintf (stderr, "%s.sess_stat: Out of memory\n", prog_name); exit (1); } memset ((char *) st.len_hist + old_size, 0, new_size - old_size); } } ++st.len_hist[priv->num_calls_completed]; } static void conn_connected (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { Sess_Private_Data *priv; Sess *sess; Conn *conn; assert (et == EV_CONN_CONNECTED && object_is_conn (obj)); conn = (Conn *) obj; sess = session_get_sess_from_conn (conn); priv = SESS_PRIVATE_DATA (sess); ++priv->num_conns; } static void call_done (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { Sess_Private_Data *priv; Sess *sess; Call *call; assert (et == EV_CALL_RECV_STOP && object_is_call (obj)); call = (Call *) obj; sess = session_get_sess_from_call (call); priv = SESS_PRIVATE_DATA (sess); ++priv->num_calls_completed; } static void dump_stats (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg) { if(!verbose){ return; } double min, avg, stddev, delta; int i; delta = timer_now() - test_time_start; avg = 0; stddev = 0; if (delta > 0) avg = st.num_completed / delta; if (st.num_rate_samples > 1) stddev = STDDEV (st.rate_sum, st.rate_sum2, st.num_rate_samples); if (st.num_rate_samples > 0) min = st.rate_min; else min = 0.0; printf ("\nSession rate [sess/s]: min %.2f avg %.2f max %.2f " "stddev %.2f (%u/%u)\n", min, avg, st.rate_max, stddev, st.num_completed, st.num_completed + st.num_failed); printf ("Session: avg %.2f connections/session\n", st.num_completed > 0 ? st.num_conns/(double) st.num_completed : 0.0); avg = 0.0; if (st.num_completed > 0) avg = st.lifetime_sum/st.num_completed; printf ("Session lifetime [s]: %.1f\n", avg); avg = 0.0; if (st.num_failed > 0) avg = st.failtime_sum/st.num_failed; printf ("Session failtime [s]: %.1f\n", avg); printf ("Session length histogram:"); for (i = 0; i <= st.longest_session; ++i) printf (" %u", st.len_hist[i]); putchar ('\n'); printf ("----------\n"); } static void init (void) { Any_Type arg; size_t size; sess_private_data_offset = object_expand (OBJ_SESS, sizeof (Sess_Private_Data)); st.len_hist_alloced = 16; size = st.len_hist_alloced*sizeof (st.len_hist[0]); st.len_hist = malloc (size); memset (st.len_hist, 0, size); st.rate_min = DBL_MAX; if (!st.len_hist) { fprintf (stderr, "%s.sess_stat: Out of memory\n", prog_name); exit (1); } arg.l = 0; event_register_handler (EV_PERF_SAMPLE, perf_sample, arg); event_register_handler (EV_SESS_NEW, sess_created, arg); event_register_handler (EV_SESS_DESTROYED, sess_destroyed, arg); event_register_handler (EV_CONN_CONNECTED, conn_connected, arg); event_register_handler (EV_CALL_RECV_STOP, call_done, arg); event_register_handler (EV_DUMP_STATS, dump_stats, arg); } static void dump (void) { double min, avg, stddev, delta; int i; FILE *fp = NULL; if (NULL == param.output_log) { fp = fopen("output.log", "a"); } else { fp = fopen(param.output_log, "a"); } delta = test_time_stop - test_time_start; avg = 0; stddev = 0; if (delta > 0) avg = st.num_completed / delta; if (st.num_rate_samples > 1) stddev = STDDEV (st.rate_sum, st.rate_sum2, st.num_rate_samples); if (st.num_rate_samples > 0) min = st.rate_min; else min = 0.0; fprintf (fp, "\nSession rate [sess/s]: min %.2f avg %.2f max %.2f " "stddev %.2f (%u/%u)\n", min, avg, st.rate_max, stddev, st.num_completed, st.num_completed + st.num_failed); fprintf (fp, "Session: avg %.2f connections/session\n", st.num_completed > 0 ? st.num_conns/(double) st.num_completed : 0.0); avg = 0.0; if (st.num_completed > 0) avg = st.lifetime_sum/st.num_completed; fprintf (fp, "Session lifetime [s]: %.1f\n", avg); avg = 0.0; if (st.num_failed > 0) avg = st.failtime_sum/st.num_failed; fprintf (fp, "Session failtime [s]: %.1f\n", avg); fprintf (fp, "Session length histogram:"); for (i = 0; i <= st.longest_session; ++i) fprintf (fp, " %u", st.len_hist[i]); fprintf(fp, "\n"); putchar ('\n'); } Stat_Collector session_stat = { "collects session-related statistics", init, no_op, no_op, dump }; ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/stat/spec_stats.c ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* This stats module was added to allow httperf to gather statistics on SPECweb99 workloads. Author: David Pariag Date: Feb 3rd, 2005 */ #include "spec_stats.h" #include #include #include #include #include #define CHAR_TO_INT(c) (c - 48) #define SPEC_CLASSES 4 #define SPEC_SIZES 9 #define NUM_SPEC_FILES (SPEC_CLASSES) * (SPEC_SIZES) + 1 #define MAX_SESSION 15 #define SPEC_HEADER 279 #define URI_INVALID (-1) #define URI_COMMAND (0) #define URI_POST (1) #define URI_STATIC_GET (2) #define URI_DYN_GET (3) int classify_uri(char *uri); int get_file_index(char *str); /* Use this struct to gather stats on each of the SPECweb99 files */ typedef struct { int requests; /* Number of times this file was requested */ int timeouts; /* Number of requests that timed out */ int missing_bytes; /* Number of requests that completed, but had missing bytes */ int size; /* Size of this file (unused for now) */ unsigned int bytes_recvd; /* Number of bytes recv'd when files of this type were requested */ double sum_resp_times; /* Sum of response times for requests of this file */ #if 0 /* might want to track and print these stats as well or to * have array of for each of these types */ int static_requests; /* times file was requested with static GET */ int dyn_get_requests; /* times file was requested with dynamic GET */ int post_requests; /* times file was requested with POST */ #endif } spec_file_data; /* Track aggregate data for each of the 36 SPECweb99 file types */ spec_file_data file_stats[NUM_SPEC_FILES]; /****************************************************** * Hardcode the file sizes for SPECweb99. We really * only want to print these at the end for information * purposes ******************************************************/ int file_sizes[NUM_SPEC_FILES] = { 102, 204,307,409,512,614,716,819,921,1024,2048,3072,4096, 5120,6144,7168,8192,9216,10240,20480,30720,40960,51200, 61440,71680,81920,92160,102400,204800,307200,409600, 512000,614400,716800,819200,921600,0 }; /* This struct gathers stats for all sessions of a given length */ typedef struct { int count; /* Number of sessions of this length that were initiated */ int timeouts; /* Number of timeouts for sessions of this length */ int requests; /* Number of requests sent over sessions of this length */ int replies; /* Number of replies that were received */ int bytes_reqd; /* Number of bytes requested over all requests */ int bytes_recvd; /* Number of bytes received over all requests */ } session_data; /* Track session stats by session-length */ session_data sess_stats[MAX_SESSION]; /* Initialize the data structures used in this module */ void spec_stats_init() { int i; for( i = 0; i < NUM_SPEC_FILES; i++ ) { file_stats[i].requests = 0; file_stats[i].timeouts = 0; file_stats[i].missing_bytes = 0; file_stats[i].size = 0; } for( i = 0; i < MAX_SESSION; i++ ) { sess_stats[i].count = 0; sess_stats[i].timeouts = 0; sess_stats[i].requests = 0; sess_stats[i].replies = 0; sess_stats[i].bytes_reqd = 0; sess_stats[i].bytes_recvd = 0; } } /* Hash a specweb uri based on the digits in the filename * The uris look like some_path/dir_/class_ * where x,y and z are digits. This hash function is based * on the x & y digits in the filename at the end of the uri. * x ranges from 0 to 3. * y ranges from 0 to 8. * This functions returns a number between 0 and 35. */ int spec_hash( char * uri ) { int x_index; int y_index; int ret = 0; /* uri is a post request and looks like /specweb99-fcgi.pl? */ if ( strlen(uri) == 19 ) { return NUM_SPEC_FILES - 1; } y_index = strlen(uri) - 1; x_index = y_index - 2; ret = (CHAR_TO_INT(uri[x_index]) * SPEC_SIZES) + (CHAR_TO_INT(uri[y_index])); if (ret < 0 || ret >= NUM_SPEC_FILES) { printf("spec_hash to return %d which is out of range\n", ret); exit(1); } return ret; } int get_spec_index( Call * c ) { char * uri = NULL; int ret = -1; int x = URI_INVALID; if( c != NULL ){ uri = c->req.iov[IE_URI].iov_base; if ( uri != NULL ) { if (!param.separate_post_stats) { x = classify_uri(uri); if (x == URI_COMMAND) { ret = -1; } else if (x == URI_POST) { if (DBG > 0) { printf("URI_POST: Content = [%s]\n", (char *) c->req.iov[IE_CONTENT].iov_base); } ret = get_file_index((char *) c->req.iov[IE_CONTENT].iov_base); } else { assert(x == URI_STATIC_GET || x == URI_DYN_GET); ret = spec_hash( uri ); } } else { ret = spec_hash( uri ); } } } if (DBG > 0) { printf("index = %d\n", ret); } return ret; } void track_spec_request(Call *c ) { int index = -1; int sess_index = 0; index = get_spec_index( c ); if ( index != -1 ) { file_stats[index].requests++; /* Track bytes requested by session length */ assert(c->conn != NULL ); assert(c->conn->basic.num_calls <= MAX_SESSION ); if ( index != NUM_SPEC_FILES - 1) { sess_index = c->conn->basic.num_calls - 1; sess_stats[sess_index].requests++; sess_stats[sess_index].bytes_reqd += file_sizes[index] + SPEC_HEADER; } } } /****************************************************************** This function is called once the first byte of a response is received. The response_start_time parameter contains the elapsed time between the sending of the request, and the receipt of the first byte of the reply ******************************************************************/ void track_spec_response(Call * c, double response_start_time ) { int index = 0; index = get_spec_index( c ); if( index != -1 ) { file_stats[index].sum_resp_times += response_start_time; } } void track_spec_reply(Call * c, double transfer_time ) { int index = 0; int sess_index = 0; index = get_spec_index( c ); if( index != -1 ) { /* Track the number of bytes received */ file_stats[index].bytes_recvd += c->reply.content_bytes; if( c->reply.content_bytes < file_sizes[index] + SPEC_HEADER) { file_stats[index].missing_bytes++; } /* Record the transfer time, as part of overall response time */ file_stats[index].sum_resp_times += transfer_time; /* Track how many bytes were recv'd by session length */ assert(c->conn != NULL ); assert(c->conn->basic.num_calls <= MAX_SESSION ); if ( index != NUM_SPEC_FILES - 1) { sess_index = c->conn->basic.num_calls - 1; sess_stats[sess_index].replies++; sess_stats[sess_index].bytes_recvd += c->reply.content_bytes; } } } void track_spec_connection(Conn * c ) { int sess_index; if( c == NULL ) return; if (DBG > 0) { printf("track_spec_connection num_calls = %d\n", c->basic.num_calls); } assert(c->basic.num_calls <= MAX_SESSION ); assert(c->basic.num_calls >= 0); sess_index = c->basic.num_calls - 1; sess_stats[sess_index].count++; } void process_spec_timeout(Conn * c ) { char * uri = NULL; int index = -1; int sess_index = 0; int x = 0; if( c == NULL ) return; if( c->recvq_tail == NULL ) return; uri = (char * ) c->recvq_tail->req.iov[IE_URI].iov_base; if( uri != NULL ) { if (!param.separate_post_stats) { if ((x = classify_uri(uri)) == URI_COMMAND) { return; } if (x == URI_POST) { if (DBG > 0) { printf("Content = [%s]\n", (char *) c->recvq_tail->req.iov[IE_CONTENT].iov_base); } index = get_file_index((char *) c->recvq_tail->req.iov[IE_CONTENT].iov_base); } else { assert(x == URI_STATIC_GET || x == URI_DYN_GET); index = spec_hash( uri ); } } else { index = spec_hash( uri ); } if (index < 0 || index >= NUM_SPEC_FILES) { printf("process_spec_timeout: index = %d is out of range\n", index); exit(1); } file_stats[index].timeouts++; file_stats[index].bytes_recvd += c->recvq_tail->reply.content_bytes; /* Track how many sessions of a particular length timed out */ assert(c->basic.num_calls <= MAX_SESSION ); if ( index != NUM_SPEC_FILES - 1 ) { sess_index = c->basic.num_calls - 1; sess_stats[sess_index].timeouts++; sess_stats[sess_index].bytes_recvd += c->recvq_tail->reply.content_bytes; } } } void print_spec_timeouts() { spec_file_data * cur; int i,j, index; double percent, percent_recvd; double avg_reqs, avg_reps, avg_response; unsigned int requested; long long total_requested = 0; long long total_recvd = 0; long long total_missing = 0; int total_requests = 0; int total_timeouts = 0; int total_conns = 0; int class_timeouts[SPEC_CLASSES] = {0,0,0,0}; int class_requests[SPEC_CLASSES] = {0,0,0,0}; long long class_bytes_requested[SPEC_CLASSES] = {0,0,0,0}; long long class_bytes_recvd[SPEC_CLASSES] = {0,0,0,0}; double class_resp_times[SPEC_CLASSES] = {0.0, 0.0, 0.0, 0.0}; /* Calculate and print per-file statistics */ printf("\nThe following table gives a breakdown of statistics by SPECweb99 file requested.\n"); printf("The column headings are:\n"); printf("Filename: The name of the file (containing directory is ignored)\n"); printf("Filesize: The size of the file in bytes\n"); printf("Timeouts: The number of requests for this file that timed out\n"); printf("Requests: The number of requests for this file\n"); printf("Timeout%s: The %s of requests for this file that timed out\n", "%", "%"); printf("Trunc'd: The number of requests that completed, but had missing byte n"); printf("Bytes Recv'd: The number of bytes received over all requests for this file\n"); printf("Bytes Req'd: The number of bytes that should have been received over all requests for this file\n"); printf("Recv'd %s: The %s of the requested bytes that were actually received\n", "%", "%"); printf("Avg Resp: The average response time when this file was requested (excludes connection time)\n"); printf("\n\n"); printf("%8s %8s %8s %8s %8s %8s %11s %11s %8s %10s\n", "Filename", "Filesize","Timeouts", "Requests", "Timeout%", "Trunc'd", "Bytes Recvd", "Bytes Reqd", "Recv'd%", "Avg Resp T"); for( i = 0; i < SPEC_CLASSES; i++ ) { for( j = 0; j < SPEC_SIZES; j++ ) { index = i * SPEC_SIZES + j; cur = &(file_stats[index]); if( cur->requests > 0 ) { /* Calculate some totals */ total_requests += cur->requests; total_timeouts += cur->timeouts; total_missing += cur->missing_bytes; /* Track total requests and timeouts by file class */ class_timeouts[i] += cur->timeouts; class_requests[i] += cur->requests; class_resp_times[i] += cur->sum_resp_times; /* Work out some percentages */ percent = 100.0 * ((double) cur->timeouts) / ((double) cur->requests) ; requested = cur->requests * (file_sizes[index] + SPEC_HEADER); percent_recvd = 100.0 * ((double)cur->bytes_recvd) / ((double)requested); avg_response = 1000.0 * cur->sum_resp_times / (double) (cur->requests - cur->timeouts); /* Track total requested and received by file class */ class_bytes_requested[i] += requested; class_bytes_recvd[i] += cur->bytes_recvd; /* Work out total requested and received (over all classes)*/ total_requested += requested; total_recvd += cur->bytes_recvd; /* Print data for this file size */ printf("%5s%d_%d %8d %8d %8d %8.2f %8d %11d %11d %8.1f %10.1f\n", "class", i,j, file_sizes[index]+SPEC_HEADER, cur->timeouts, cur->requests, percent, cur->missing_bytes, cur->bytes_recvd, requested, percent_recvd, avg_response ); } } /* for j */ } /* for i */ //requested, percent_recvd, avg_response ); percent = 100.0 * ((double) total_timeouts) / ((double) total_requests); percent_recvd = 100.0 * ((double) total_recvd) / ((double) total_requested ); printf("%8s %8s %8d %8d %8.2f %8lld %11lld %11lld %8.1f %10s\n", "Total", " ", total_timeouts, total_requests, percent, total_missing, total_recvd, total_requested, percent_recvd, " "); if (param.separate_post_stats) { cur = &(file_stats[NUM_SPEC_FILES-1]); percent = 100.0 * ((double) cur->timeouts) / ((double) cur->requests); avg_response = 1000.0 * cur->sum_resp_times / (double) (cur->requests - cur->timeouts); printf("%8s %8s %8d %8d %8.2f %8d %11d %11s %8s %10.1f\n", "POST", " ", cur->timeouts, cur->requests, percent, cur->missing_bytes, cur->bytes_recvd, " ", " ", avg_response); } /* Calculate and print per-class statistics */ printf("\nSPECweb99 Timeouts (by class):\n"); printf("%8s %10s %8s %9s %12s %11s %8s %9s\n", "Class", "Timeouts", "Requests", "Timeout%", "Bytes recv'd", "Bytes req'd", "Recv'd%", "Resp-time" ); for( i = 0; i < SPEC_CLASSES; i++ ) { percent = 100.0 * ((double) class_timeouts[i]) / ((double) class_requests[i]); percent_recvd = 100.0 * ((double) class_bytes_recvd[i]) / ((double) class_bytes_requested[i]); avg_response = 1000.0 * (class_resp_times[i] / (double) (class_requests[i] - class_timeouts[i])); printf("%7s%1d %10d %8d %9.2f %12lld %11lld %8.2f %9.1f\n", "class", i, class_timeouts[i], class_requests[i], percent, class_bytes_recvd[i], class_bytes_requested[i], percent_recvd, avg_response); } /* Calculate and print per-session-length statistics */ printf("\nSPECweb99 Timeouts (by session length):\n"); printf("%6s %10s %10s %10s %10s %10s %12s %12s %8s\n", "Length", "Count", "Timeouts", "Timeout%", "Avg-req", "Avg-rep", "Bytes-recvd", "Bytes-reqd", "Recvd%"); /* Re-calculate totals just to make sure (they should be the same as above) */ total_conns = total_requested = total_recvd = total_timeouts = total_requests = 0; for(i=0; i< MAX_SESSION; i++ ) { if( sess_stats[i].requests > 0 ) { total_requests += sess_stats[i].requests; total_timeouts += sess_stats[i].timeouts; total_recvd += sess_stats[i].bytes_recvd; total_conns += sess_stats[i].count; total_requested += sess_stats[i].bytes_reqd; percent = 100.0 * ((double)sess_stats[i].timeouts / (double) sess_stats[i].count); avg_reqs = ((double)sess_stats[i].requests / (double) sess_stats[i].count); avg_reps = ((double)sess_stats[i].replies / (double) sess_stats[i].count); percent_recvd = 100.0 * ((double) sess_stats[i].bytes_recvd / (double) sess_stats[i].bytes_reqd); printf("%4s%2.2d %10d %10d %10.2f %10.2f %10.2f %12d %12d %8.2f\n", "sess", i+1, sess_stats[i].count, sess_stats[i].timeouts, percent, avg_reqs, avg_reps, sess_stats[i].bytes_recvd, sess_stats[i].bytes_reqd, percent_recvd ); } } /* for i */ percent = 100.0 * ((double) total_timeouts) / ((double) total_conns); percent_recvd = 100.0 * ((double) total_recvd) / ((double) total_requested ); printf("%6s %10d %10d %10.2f %10s %10s %12lld %12lld %8.2f\n", "Total", total_conns, total_timeouts, percent, " ", " ", total_recvd, total_requested, percent_recvd); } int classify_uri(char *uri) { int result = URI_INVALID; char *p = 0; if ((p = strchr(uri, '?')) != NULL) { /* post requests end with the ? */ if ((strcmp(p, "?")) == '\0') { result = URI_POST; } else if (strncmp(p+1, "command", 7) == 0) { result = URI_COMMAND; } else { /* not a command but is dynamic */ result = URI_DYN_GET; } } else { /* static request */ result = URI_STATIC_GET; } if (DBG > 0) { printf("returning result = %d\n", result); } return result; } /* Figure out which class and number are used and combine them for a file index * urlroot=/specweb99/file_set/&dir=00000&class=2&num=1&client=10018^M */ #define CLASS_INDEX (45) #define NUM_INDEX (51) int get_file_index(char *str) { /* very fast but very fragile method */ int class = CHAR_TO_INT(str[CLASS_INDEX]); int num = CHAR_TO_INT(str[NUM_INDEX]); if (DBG > 0) { printf("class%c_%c\n", str[CLASS_INDEX], str[NUM_INDEX]); } if (class < 0 || class >= SPEC_CLASSES) { printf("get_file_index: class = %d is out of range\n", class); exit(1); } if (num < 0 || num >= SPEC_SIZES) { printf("get_file_index: num = %d is out of range\n", num); exit(1); } return (class * SPEC_SIZES) + num; } ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/stat/spec_stats.h ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef SPEC_STATS #define SPEC_STATS #include #include /* Initialize the data structures used for tracking SPECweb99 statistics */ void spec_stats_init(); /* This function is called when a connection is established. */ void track_spec_connection(Conn * c ); /* This function is called once a request has been sent to the server*/ void track_spec_request(Call *c ); /* This function is called once the first byte of a reply is received from the server. */ void track_spec_response(Call * c, double response_start_time); /* This function is called when the last byte of a reply is received from the server */ void track_spec_reply(Call * c, double transfer_time); /* This function is called when a connection times out. It should only track timeouts for those connections on which a request was sent */ void process_spec_timeout(Conn * c ); /* Print a summary of the SPECweb99 statistics. The summary focuses on timeouts, but also includes several other statistics */ void print_spec_timeouts(); #endif /* SPEC_STATS */ ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/stat/stats.h ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef stats_h #define stats_h #include #define SQUARE(f) ((f)*(f)) #define VAR(s,s2,n) (((n) < 2) ? 0.0 : ((s2) - SQUARE(s)/(n)) / ((n) - 1)) #define STDDEV(s,s2,n) (((n) < 2) ? 0.0 : sqrt (VAR ((s), (s2), (n)))) #endif /* stats_h */ ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/sys_sched_affinity.c ================================================ #ifdef HAVE_SCHED_AFFINITY #ifdef __linux__ #include #include long sched_setaffinity_videoperf(pid_t pid, unsigned int len, unsigned long *cpu_mask) { return syscall(SYS_sched_setaffinity, pid, len, cpu_mask); } long sched_getaffinity_videoperf(pid_t pid, unsigned int len, unsigned long *cpu_mask) { return syscall(SYS_sched_getaffinity, pid, len, cpu_mask); } #endif /* __linux__ */ #endif /* HAVE_SCHED_AFFINITY */ ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/sys_sched_affinity.h ================================================ #ifndef SYS_SCHED_AFFINITY_H #define SYS_SCHED_AFFINITY_H #ifdef HAVE_SCHED_AFFINITY #ifdef __linux__ extern long sched_setaffinity_videoperf(pid_t pid, unsigned int len, unsigned long *cpu_mask); extern long sched_getaffinity_videoperf(pid_t pid, unsigned int len, unsigned long *cpu_mask); #endif /* HAVE_SCHED_AFFINITY */ #endif /* __linux__ */ #endif /* SYS_SCHED_AFFINITY_H */ ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/tags ================================================ !_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ !_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ !_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/ !_TAG_PROGRAM_NAME Exuberant Ctags // !_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/ !_TAG_PROGRAM_VERSION 5.9~svn20110310 // ALIGN object.c 38;" d file: Any_Type httperf.h /^Any_Type;$/;" t typeref:union:__anon8 BIG_FD_CLR core.c /^void BIG_FD_CLR(int fd, big_fd_set *fdsetp) $/;" f BIG_FD_ISSET core.c /^int BIG_FD_ISSET(int fd, big_fd_set *fdsetp)$/;" f BIG_FD_SET core.c /^void BIG_FD_SET(int fd, big_fd_set *fdsetp)$/;" f BIN_WIDTH stat/basic.c 54;" d file: BITSPERLONG core.c 62;" d file: BURST gen/videosesslog.c /^typedef struct burst BURST;$/;" t typeref:struct:burst file: CALL_PRIVATE_DATA gen/sess_cookie.c 52;" d file: CALL_PRIVATE_DATA gen/session.c 75;" d file: CALL_PRIVATE_DATA gen/uri_wset.c 38;" d file: CALL_PRIVATE_DATA gen/wsesspage.c 48;" d file: CALL_PRIVATE_DATA stat/print_reply.c 47;" d file: CC Makefile /^CC = gcc$/;" m CC gen/Makefile /^CC = gcc$/;" m CC lib/Makefile /^CC = gcc$/;" m CC stat/Makefile /^CC = gcc$/;" m CFLAGS Makefile /^CFLAGS = -g -O2 -Wall $/;" m CFLAGS gen/Makefile /^CFLAGS = -g -O2 -Wall $/;" m CFLAGS lib/Makefile /^CFLAGS = -g -O2 -Wall $/;" m CFLAGS stat/Makefile /^CFLAGS = -g -O2 -Wall $/;" m CHAR_TO_INT stat/spec_stats.c 40;" d file: CLASS_INDEX stat/spec_stats.c 478;" d file: COMPILE Makefile /^COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $/;" m COMPILE gen/Makefile /^COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -static -static-libgcc$/;" m COMPILE lib/Makefile /^COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -static -static-libgcc$/;" m COMPILE stat/Makefile /^COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -static -static-libgcc$/;" m CONN_ERR_COUNT httperf.h 277;" d CONN_ERR_HASH_LOOKUP_FAILED httperf.h 274;" d CONN_ERR_NOT_SET httperf.h 272;" d CONN_ERR_NO_MORE_PORTS httperf.h 273;" d CONN_ERR_STATE_PAST_CLOSING httperf.h 275;" d CONN_PRIVATE_DATA gen/call_seq.c 35;" d file: CONN_PRIVATE_DATA gen/session.c 72;" d file: CPPFLAGS Makefile /^CPPFLAGS = -DNDEBUG -D_GNU_SOURCE -D_XOPEN_SOURCE$/;" m CPPFLAGS gen/Makefile /^CPPFLAGS = -DNDEBUG -D_GNU_SOURCE -D_XOPEN_SOURCE$/;" m CPPFLAGS lib/Makefile /^CPPFLAGS = -DNDEBUG -D_GNU_SOURCE -D_XOPEN_SOURCE$/;" m CPPFLAGS stat/Makefile /^CPPFLAGS = -DNDEBUG -D_GNU_SOURCE -D_XOPEN_SOURCE$/;" m Call call.h /^Call;$/;" t typeref:struct:Call Call call.h /^typedef struct Call$/;" s Call_Private_Data gen/sess_cookie.c /^Call_Private_Data;$/;" t typeref:struct:Call_Private_Data file: Call_Private_Data gen/sess_cookie.c /^typedef struct Call_Private_Data$/;" s file: Call_Private_Data gen/session.c /^Call_Private_Data;$/;" t typeref:struct:Call_Private_Data file: Call_Private_Data gen/session.c /^typedef struct Call_Private_Data$/;" s file: Call_Private_Data gen/wsesspage.c /^Call_Private_Data;$/;" t typeref:struct:Call_Private_Data file: Call_Private_Data gen/wsesspage.c /^typedef struct Call_Private_Data$/;" s file: Call_Private_Data stat/print_reply.c /^Call_Private_Data;$/;" t typeref:struct:Call_Private_Data file: Call_Private_Data stat/print_reply.c /^typedef struct Call_Private_Data$/;" s file: Cmdline_Params httperf.h /^Cmdline_Params;$/;" t typeref:struct:Cmdline_Params Cmdline_Params httperf.h /^typedef struct Cmdline_Params$/;" s Conn conn.h /^Conn;$/;" t typeref:struct:Conn Conn conn.h /^typedef struct Conn$/;" s Conn_Info gen/session.c /^ struct Conn_Info$/;" s struct:Sess_Private_Data file: Conn_Private_Data gen/call_seq.c /^Conn_Private_Data;$/;" t typeref:struct:Conn_Private_Data file: Conn_Private_Data gen/call_seq.c /^typedef struct Conn_Private_Data$/;" s file: Conn_Private_Data gen/session.c /^Conn_Private_Data;$/;" t typeref:struct:Conn_Private_Data file: Conn_Private_Data gen/session.c /^typedef struct Conn_Private_Data$/;" s file: Conn_State conn.h /^Conn_State;$/;" t typeref:enum:Conn_State Conn_State conn.h /^typedef enum Conn_State$/;" g DBG httperf.h 258;" d DBG httperf.h 260;" d DEFAULT_METHOD call.c 49;" d file: DEFS Makefile /^DEFS = -DHAVE_CONFIG_H$/;" m DEFS gen/Makefile /^DEFS = -DHAVE_CONFIG_H$/;" m DEFS lib/Makefile /^DEFS = -DHAVE_CONFIG_H$/;" m DEFS stat/Makefile /^DEFS = -DHAVE_CONFIG_H$/;" m DETERMINISTIC httperf.h /^ DETERMINISTIC, \/* also called fixed-rate *\/$/;" e enum:Dist_Type Dist_Type httperf.h /^Dist_Type;$/;" t typeref:enum:Dist_Type Dist_Type httperf.h /^typedef enum Dist_Type$/;" g EV_CALL_DESTROYED event.h /^ EV_CALL_DESTROYED,$/;" e enum:Event_Type EV_CALL_ISSUE event.h /^ EV_CALL_ISSUE,$/;" e enum:Event_Type EV_CALL_NEW event.h /^ EV_CALL_NEW,$/;" e enum:Event_Type EV_CALL_RECV_DATA event.h /^ EV_CALL_RECV_DATA,$/;" e enum:Event_Type EV_CALL_RECV_FOOTER event.h /^ EV_CALL_RECV_FOOTER,$/;" e enum:Event_Type EV_CALL_RECV_HDR event.h /^ EV_CALL_RECV_HDR,$/;" e enum:Event_Type EV_CALL_RECV_RAW_DATA event.h /^ EV_CALL_RECV_RAW_DATA,$/;" e enum:Event_Type EV_CALL_RECV_START event.h /^ EV_CALL_RECV_START,$/;" e enum:Event_Type EV_CALL_RECV_STOP event.h /^ EV_CALL_RECV_STOP,$/;" e enum:Event_Type EV_CALL_SEND_RAW_DATA event.h /^ EV_CALL_SEND_RAW_DATA,$/;" e enum:Event_Type EV_CALL_SEND_START event.h /^ EV_CALL_SEND_START,$/;" e enum:Event_Type EV_CALL_SEND_STOP event.h /^ EV_CALL_SEND_STOP,$/;" e enum:Event_Type EV_CONN_CLOSE event.h /^ EV_CONN_CLOSE, \/* connection closed *\/$/;" e enum:Event_Type EV_CONN_CONNECTED event.h /^ EV_CONN_CONNECTED,$/;" e enum:Event_Type EV_CONN_CONNECTING event.h /^ EV_CONN_CONNECTING,$/;" e enum:Event_Type EV_CONN_DESTROYED event.h /^ EV_CONN_DESTROYED,$/;" e enum:Event_Type EV_CONN_FAILED event.h /^ EV_CONN_FAILED, \/* failed for reasons other than timeout *\/$/;" e enum:Event_Type EV_CONN_NEW event.h /^ EV_CONN_NEW,$/;" e enum:Event_Type EV_CONN_TIMEOUT event.h /^ EV_CONN_TIMEOUT,$/;" e enum:Event_Type EV_DUMP_STATS event.h /^ EV_DUMP_STATS,$/;" e enum:Event_Type EV_HOSTNAME_LOOKUP_START event.h /^ EV_HOSTNAME_LOOKUP_START,$/;" e enum:Event_Type EV_HOSTNAME_LOOKUP_STOP event.h /^ EV_HOSTNAME_LOOKUP_STOP,$/;" e enum:Event_Type EV_NUM_EVENT_TYPES event.h /^ EV_NUM_EVENT_TYPES$/;" e enum:Event_Type EV_PERF_SAMPLE event.h /^ EV_PERF_SAMPLE,$/;" e enum:Event_Type EV_SESS_DESTROYED event.h /^ EV_SESS_DESTROYED,$/;" e enum:Event_Type EV_SESS_FAILED event.h /^ EV_SESS_FAILED,$/;" e enum:Event_Type EV_SESS_NEW event.h /^ EV_SESS_NEW,$/;" e enum:Event_Type EXPONENTIAL httperf.h /^ EXPONENTIAL \/* with mean mean_iat *\/$/;" e enum:Dist_Type Event event.h /^Event;$/;" t typeref:struct:Event Event event.h /^typedef struct Event$/;" s Event_Action event.c /^Event_Action;$/;" t typeref:struct:Event_Action file: Event_Action event.c /^typedef struct Event_Action$/;" s file: Event_Handler event.h /^typedef void (*Event_Handler) (Event_Type type, Object *obj,$/;" t Event_Type event.h /^Event_Type;$/;" t typeref:enum:Event_Type Event_Type event.h /^typedef enum Event_Type$/;" g FALSE gen/videosesslog.c 101;" d file: HASH_TABLE_SIZE core.c 59;" d file: HAVE_ALLOCA config.h 15;" d HAVE_ALLOCA_H config.h 18;" d HAVE_FCNTL_H config.h 78;" d HAVE_GETPAGESIZE config.h 51;" d HAVE_GETTIMEOFDAY config.h 54;" d HAVE_LIBCRYPTO config.h 93;" d HAVE_LIBM config.h 96;" d HAVE_LIBSSL config.h 99;" d HAVE_MMAP config.h 24;" d HAVE_OPENSSL_SSL_H config.h 81;" d HAVE_SELECT config.h 57;" d HAVE_SOCKET config.h 60;" d HAVE_SSL config.h 102;" d HAVE_STRDUP config.h 63;" d HAVE_STRERROR config.h 66;" d HAVE_STRTOD config.h 69;" d HAVE_STRTOL config.h 72;" d HAVE_STRTOUL config.h 75;" d HAVE_SYS_IOCTL_H config.h 84;" d HAVE_SYS_TIME_H config.h 87;" d HAVE_UNISTD_H config.h 90;" d HAVE_VPRINTF config.h 27;" d HM_DELETE gen/videosesslog.c /^ HM_DELETE, HM_GET, HM_HEAD, HM_OPTIONS, HM_POST, HM_PUT, HM_TRACE,$/;" e enum:__anon7 file: HM_GET gen/videosesslog.c /^ HM_DELETE, HM_GET, HM_HEAD, HM_OPTIONS, HM_POST, HM_PUT, HM_TRACE,$/;" e enum:__anon7 file: HM_HEAD gen/videosesslog.c /^ HM_DELETE, HM_GET, HM_HEAD, HM_OPTIONS, HM_POST, HM_PUT, HM_TRACE,$/;" e enum:__anon7 file: HM_LEN gen/videosesslog.c /^ HM_LEN$/;" e enum:__anon7 file: HM_OPTIONS gen/videosesslog.c /^ HM_DELETE, HM_GET, HM_HEAD, HM_OPTIONS, HM_POST, HM_PUT, HM_TRACE,$/;" e enum:__anon7 file: HM_POST gen/videosesslog.c /^ HM_DELETE, HM_GET, HM_HEAD, HM_OPTIONS, HM_POST, HM_PUT, HM_TRACE,$/;" e enum:__anon7 file: HM_PUT gen/videosesslog.c /^ HM_DELETE, HM_GET, HM_HEAD, HM_OPTIONS, HM_POST, HM_PUT, HM_TRACE,$/;" e enum:__anon7 file: HM_TRACE gen/videosesslog.c /^ HM_DELETE, HM_GET, HM_HEAD, HM_OPTIONS, HM_POST, HM_PUT, HM_TRACE,$/;" e enum:__anon7 file: HTTPERF_OBJS Makefile /^HTTPERF_OBJS = httperf.o object.o call.o conn.o sess.o core.o event.o \\$/;" m IE_BLANK call.h /^ IE_BLANK, \/* space separating method from location *\/$/;" e enum:IOV_Element IE_CONTENT call.h /^ IE_CONTENT,$/;" e enum:IOV_Element IE_FIRST_HEADER call.h /^ IE_FIRST_HEADER,$/;" e enum:IOV_Element IE_HOST call.h /^ IE_HOST, \/* for the "Host:" header *\/$/;" e enum:IOV_Element IE_LAST_HEADER call.h /^ IE_LAST_HEADER = IE_FIRST_HEADER + MAX_EXTRA_HEADERS - 1,$/;" e enum:IOV_Element IE_LEN call.h /^ IE_LEN \/* must be last *\/$/;" e enum:IOV_Element IE_LOC call.h /^ IE_LOC, \/* for proxy requests only *\/$/;" e enum:IOV_Element IE_METHOD call.h /^ IE_METHOD,$/;" e enum:IOV_Element IE_NEWLINE1 call.h /^ IE_NEWLINE1,$/;" e enum:IOV_Element IE_NEWLINE2 call.h /^ IE_NEWLINE2,$/;" e enum:IOV_Element IE_PROTL call.h /^ IE_PROTL,$/;" e enum:IOV_Element IE_URI call.h /^ IE_URI,$/;" e enum:IOV_Element INCLUDES Makefile /^INCLUDES = -I$(top_srcdir)\/include -I$(top_builddir) -I$(top_srcdir) -I$(top_srcdir)\/lib -I\/usr\/kerberos\/include$/;" m INCLUDES gen/Makefile /^INCLUDES = -I$(top_builddir) -I$(srcdir) -I$(top_srcdir) -I$(top_srcdir)\/lib \\$/;" m INCLUDES lib/Makefile /^INCLUDES = -I$(top_builddir) -I$(top_srcdir) -I$(top_srcdir)\/lib \\$/;" m INCLUDES stat/Makefile /^INCLUDES = -I$(top_builddir) -I$(srcdir) -I$(top_srcdir) -I$(top_srcdir)\/lib \\$/;" m INSTALL Makefile /^INSTALL = \/usr\/bin\/install -c$/;" m INSTALL_DATA Makefile /^INSTALL_DATA = ${INSTALL} -m 644$/;" m INSTALL_PROGRAM Makefile /^INSTALL_PROGRAM = ${INSTALL}$/;" m IOV_Element call.h /^IOV_Element;$/;" t typeref:enum:IOV_Element IOV_Element call.h /^typedef enum IOV_Element$/;" g LDFLAGS Makefile /^LDFLAGS = $/;" m LDFLAGS gen/Makefile /^LDFLAGS = $/;" m LDFLAGS lib/Makefile /^LDFLAGS = $/;" m LDFLAGS stat/Makefile /^LDFLAGS = $/;" m LIBGEN_OBJS gen/Makefile /^LIBGEN_OBJS = call_seq.o conn_rate.o misc.o rate.o session.o \\$/;" m LIBS Makefile /^LIBS = -lssl -lcrypto -lm $/;" m LIBS gen/Makefile /^LIBS = -lssl -lcrypto -lm $/;" m LIBS lib/Makefile /^LIBS = -lssl -lcrypto -lm $/;" m LIBS stat/Makefile /^LIBS = -lssl -lcrypto -lm $/;" m LIBSTAT_OBJS stat/Makefile /^LIBSTAT_OBJS = basic.o sess_stat.o print_reply.o spec_stats.o call_stats.o$/;" m LIBUTIL_OBJS lib/Makefile /^LIBUTIL_OBJS = getopt.o getopt1.o ssl_writev.o$/;" m LINK Makefile /^LINK = $(CC) $(LDFLAGS) -o $@$/;" m LINK gen/Makefile /^LINK = $(CC) $(LDFLAGS) -static -static-libgcc -o $@$/;" m LINK lib/Makefile /^LINK = $(CC) $(LDFLAGS) -static -static-libgcc -o $@$/;" m LINK stat/Makefile /^LINK = $(CC) $(LDFLAGS) -static -static-libgcc -o $@$/;" m Load_Generator httperf.h /^Load_Generator;$/;" t typeref:struct:Load_Generator Load_Generator httperf.h /^typedef struct Load_Generator$/;" s MAX_CONN gen/session.c 66;" d file: MAX_COOKIE_LEN gen/sess_cookie.c 47;" d file: MAX_ERRNO stat/basic.c 67;" d file: MAX_EXTRA_HEADERS call.h 35;" d MAX_HDR_LINE_LEN conn.h 43;" d MAX_HOSTNAME_LEN httperf.c 83;" d file: MAX_IP_PORT core.c 61;" d file: MAX_LIFETIME stat/basic.c 53;" d file: MAX_LOG_FILES httperf.h 47;" d MAX_NUM_OPS event.c 33;" d file: MAX_PIPED gen/session.c 67;" d file: MAX_SESSION stat/spec_stats.c 44;" d file: MAX_SESSION_TEMPLATES gen/videosesslog.c 95;" d file: MAX_SVR_PORTS httperf.h 116;" d MAX_URI_LEN gen/uri_wset.c 37;" d file: MIN gen/call_seq.c 38;" d file: MIN_IP_PORT core.c 60;" d file: MKDIR Makefile /^MKDIR = $(top_srcdir)\/mkinstalldirs$/;" m NELEMS httperf.h 40;" d NONOPTION_P lib/getopt.c 446;" d file: NULL lib/getopt1.c 59;" d file: NUM_BINS stat/basic.c 58;" d file: NUM_BINS stat/basic.c 62;" d file: NUM_INDEX stat/spec_stats.c 479;" d file: NUM_RATES httperf.h 44;" d NUM_SPEC_FILES stat/spec_stats.c 43;" d file: OBJ_CALL object.h /^ OBJ_CALL, \/* call object *\/$/;" e enum:Object_Type OBJ_CONN object.h /^ OBJ_CONN, \/* connection object *\/$/;" e enum:Object_Type OBJ_NUM_TYPES object.h /^ OBJ_NUM_TYPES$/;" e enum:Object_Type OBJ_SESS object.h /^ OBJ_SESS, \/* session object *\/$/;" e enum:Object_Type Object object.h /^Object;$/;" t typeref:struct:Object Object object.h /^typedef struct Object$/;" s Object_Type object.h /^Object_Type;$/;" t typeref:enum:Object_Type Object_Type object.h /^typedef enum Object_Type$/;" g PATHLEN http.c 365;" d file: PERMUTE lib/getopt.c /^ REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER$/;" e enum:__anon12 file: PRINT_BODY httperf.h 114;" d PRINT_HEADER httperf.h 113;" d P_CMD gen/wsesspage.c /^ P_CMD, \/* we saw a `<' and are scanning for the end of CMD *\/$/;" e enum:Call_Private_Data::__anon6 file: P_DASH_ONE gen/wsesspage.c /^ P_DASH_ONE, \/* looking for the first dash of a comment close *\/$/;" e enum:Call_Private_Data::__anon6 file: P_DASH_TWO gen/wsesspage.c /^ P_DASH_TWO, \/* looking for the second dash of a comment close *\/$/;" e enum:Call_Private_Data::__anon6 file: P_DATA gen/wsesspage.c /^ P_DATA, \/* we're looking for "data" *\/$/;" e enum:Call_Private_Data::__anon6 file: P_HTML gen/wsesspage.c /^ P_HTML,$/;" e enum:Call_Private_Data::__anon6 file: P_INITIAL gen/wsesspage.c /^ P_INITIAL,$/;" e enum:Call_Private_Data::__anon6 file: P_LQUOTE gen/wsesspage.c /^ P_LQUOTE, \/* we're looking for the left quote of a URI *\/$/;" e enum:Call_Private_Data::__anon6 file: P_NAKED_URI gen/wsesspage.c /^ P_NAKED_URI, \/* we're looking for an unquoted URI *\/$/;" e enum:Call_Private_Data::__anon6 file: P_QUOTED_URI gen/wsesspage.c /^ P_QUOTED_URI \/* we're looking for a quoted URI *\/$/;" e enum:Call_Private_Data::__anon6 file: P_RANGLE gen/wsesspage.c /^ P_RANGLE, \/* looking for '>' *\/$/;" e enum:Call_Private_Data::__anon6 file: P_SRC gen/wsesspage.c /^ P_SRC, \/* we're looking for "src" *\/$/;" e enum:Call_Private_Data::__anon6 file: RANLIB Makefile /^RANLIB = ranlib$/;" m RANLIB gen/Makefile /^RANLIB = ranlib$/;" m RANLIB lib/Makefile /^RANLIB = ranlib$/;" m RANLIB stat/Makefile /^RANLIB = ranlib$/;" m RATE_INTERVAL httperf.c 80;" d file: REQ gen/videosesslog.c /^typedef struct req REQ;$/;" t typeref:struct:req file: REQUIRE_ORDER lib/getopt.c /^ REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER$/;" e enum:__anon12 file: RETSIGTYPE config.h 30;" d RETURN_IN_ORDER lib/getopt.c /^ REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER$/;" e enum:__anon12 file: Rate_Generator gen/rate.h /^Rate_Generator;$/;" t typeref:struct:Rate_Generator Rate_Generator gen/rate.h /^typedef struct Rate_Generator$/;" s Rate_Info httperf.h /^Rate_Info;$/;" t typeref:struct:Rate_Info Rate_Info httperf.h /^typedef struct Rate_Info$/;" s SC_BIND core.c /^ SC_BIND, SC_CONNECT, SC_READ, SC_SELECT, SC_SOCKET, SC_WRITEV,$/;" e enum:Syscalls file: SC_CONNECT core.c /^ SC_BIND, SC_CONNECT, SC_READ, SC_SELECT, SC_SOCKET, SC_WRITEV,$/;" e enum:Syscalls file: SC_EPOLL_CREATE core.c /^ SC_EPOLL_CREATE, SC_EPOLL_CTL, SC_EPOLL_WAIT,$/;" e enum:Syscalls file: SC_EPOLL_CTL core.c /^ SC_EPOLL_CREATE, SC_EPOLL_CTL, SC_EPOLL_WAIT,$/;" e enum:Syscalls file: SC_EPOLL_WAIT core.c /^ SC_EPOLL_CREATE, SC_EPOLL_CTL, SC_EPOLL_WAIT,$/;" e enum:Syscalls file: SC_NUM_SYSCALLS core.c /^ SC_NUM_SYSCALLS$/;" e enum:Syscalls file: SC_READ core.c /^ SC_BIND, SC_CONNECT, SC_READ, SC_SELECT, SC_SOCKET, SC_WRITEV,$/;" e enum:Syscalls file: SC_SELECT core.c /^ SC_BIND, SC_CONNECT, SC_READ, SC_SELECT, SC_SOCKET, SC_WRITEV,$/;" e enum:Syscalls file: SC_SOCKET core.c /^ SC_BIND, SC_CONNECT, SC_READ, SC_SELECT, SC_SOCKET, SC_WRITEV,$/;" e enum:Syscalls file: SC_SSL_READ core.c /^ SC_SSL_READ, SC_SSL_WRITEV,$/;" e enum:Syscalls file: SC_SSL_WRITEV core.c /^ SC_SSL_READ, SC_SSL_WRITEV,$/;" e enum:Syscalls file: SC_WRITEV core.c /^ SC_BIND, SC_CONNECT, SC_READ, SC_SELECT, SC_SOCKET, SC_WRITEV,$/;" e enum:Syscalls file: SESS_PRIVATE_DATA gen/sess_cookie.c 49;" d file: SESS_PRIVATE_DATA gen/session.c 69;" d file: SESS_PRIVATE_DATA gen/videosesslog.c 104;" d file: SESS_PRIVATE_DATA gen/wsess.c 43;" d file: SESS_PRIVATE_DATA gen/wsesspage.c 50;" d file: SESS_PRIVATE_DATA stat/sess_stat.c 63;" d file: SHELL Makefile /^SHELL=\/bin\/sh$/;" m SHELL gen/Makefile /^SHELL=\/bin\/sh$/;" m SHELL lib/Makefile /^SHELL=\/bin\/sh$/;" m SHELL stat/Makefile /^SHELL=\/bin\/sh$/;" m SIZEOF_LONG config.h 105;" d SOL_TCP core.c 93;" d file: SPEC_CLASSES stat/spec_stats.c 41;" d file: SPEC_HEADER stat/spec_stats.c 45;" d file: SPEC_SIZES stat/spec_stats.c 42;" d file: SPEC_STATS stat/spec_stats.h 26;" d SQUARE stat/stats.h 30;" d SSL_version configure /^SSL_version()$/;" f SSL_writev lib/ssl_writev.c /^SSL_writev (SSL *ssl, const struct iovec *vector, int count)$/;" f STATS_INTERVAL httperf.c 81;" d file: STDC_HEADERS config.h 45;" d STDDEV stat/stats.h 32;" d SUBDIRS Makefile /^SUBDIRS = lib gen stat$/;" m SYSCALL core.c 110;" d file: SYSCALL core.c 142;" d file: SYS_SCHED_AFFINITY_H sys_sched_affinity.h 2;" d S_CLOSING conn.h /^ S_CLOSING,$/;" e enum:Conn_State S_CONNECTED conn.h /^ S_CONNECTED,$/;" e enum:Conn_State S_CONNECTING conn.h /^ S_CONNECTING,$/;" e enum:Conn_State S_FREE conn.h /^ S_FREE$/;" e enum:Conn_State S_INITIAL conn.h /^ S_INITIAL,$/;" e enum:Conn_State S_REPLY_CHUNKED conn.h /^ S_REPLY_CHUNKED,$/;" e enum:Conn_State S_REPLY_CONTINUE conn.h /^ S_REPLY_CONTINUE,$/;" e enum:Conn_State S_REPLY_DATA conn.h /^ S_REPLY_DATA,$/;" e enum:Conn_State S_REPLY_DONE conn.h /^ S_REPLY_DONE,$/;" e enum:Conn_State S_REPLY_FOOTER conn.h /^ S_REPLY_FOOTER,$/;" e enum:Conn_State S_REPLY_HEADER conn.h /^ S_REPLY_HEADER,$/;" e enum:Conn_State S_REPLY_STATUS conn.h /^ S_REPLY_STATUS,$/;" e enum:Conn_State Sess sess.h /^Sess;$/;" t typeref:struct:Sess Sess sess.h /^typedef struct Sess$/;" s Sess_Private_Data gen/sess_cookie.c /^Sess_Private_Data;$/;" t typeref:struct:Sess_Private_Data file: Sess_Private_Data gen/sess_cookie.c /^typedef struct Sess_Private_Data$/;" s file: Sess_Private_Data gen/session.c /^Sess_Private_Data;$/;" t typeref:struct:Sess_Private_Data file: Sess_Private_Data gen/session.c /^typedef struct Sess_Private_Data$/;" s file: Sess_Private_Data gen/videosesslog.c /^struct Sess_Private_Data$/;" s file: Sess_Private_Data gen/videosesslog.c /^typedef struct Sess_Private_Data Sess_Private_Data;$/;" t typeref:struct:Sess_Private_Data file: Sess_Private_Data gen/wsess.c /^Sess_Private_Data;$/;" t typeref:struct:Sess_Private_Data file: Sess_Private_Data gen/wsess.c /^typedef struct Sess_Private_Data$/;" s file: Sess_Private_Data gen/wsesspage.c /^Sess_Private_Data;$/;" t typeref:struct:Sess_Private_Data file: Sess_Private_Data gen/wsesspage.c /^typedef struct Sess_Private_Data$/;" s file: Sess_Private_Data stat/sess_stat.c /^Sess_Private_Data;$/;" t typeref:struct:Sess_Private_Data file: Sess_Private_Data stat/sess_stat.c /^typedef struct Sess_Private_Data$/;" s file: Session_Log_Desc gen/videosesslog.c /^struct Session_Log_Desc$/;" s file: Session_Log_Desc gen/videosesslog.c /^typedef struct Session_Log_Desc Session_Log_Desc;$/;" t typeref:struct:Session_Log_Desc file: Stat_Collector httperf.h /^Stat_Collector;$/;" t typeref:struct:Stat_Collector Stat_Collector httperf.h /^typedef struct Stat_Collector$/;" s Syscalls core.c /^ enum Syscalls$/;" g file: TIMER_INTERVAL timer.h 32;" d TIME_BEGIN core.c 102;" d file: TIME_BEGIN core.c 105;" d file: TIME_END core.c 103;" d file: TIME_END core.c 106;" d file: TIME_WITH_SYS_TIME config.h 48;" d TRUE gen/videosesslog.c 98;" d file: TTEST_OBJS Makefile /^TTEST_OBJS = ttest.o timer.o$/;" m TV_TO_SEC httperf.h 41;" d Time httperf.h /^typedef double Time;$/;" t Timer timer.h /^Timer;$/;" t typeref:struct:Timer Timer timer.h /^typedef struct Timer$/;" s Timer_Callback timer.h /^typedef void (*Timer_Callback) (struct Timer *t, Any_Type arg);$/;" t Timer_Queue timer.h /^Timer_Queue;$/;" t typeref:struct:Timer_Queue Timer_Queue timer.h /^typedef struct Timer_Queue$/;" s UNIFORM httperf.h /^ UNIFORM, \/* over interval [min_iat,max_iat) *\/$/;" e enum:Dist_Type URI_COMMAND stat/spec_stats.c 48;" d file: URI_DYN_GET stat/spec_stats.c 51;" d file: URI_INVALID stat/spec_stats.c 47;" d file: URI_POST stat/spec_stats.c 49;" d file: URI_SIZE stat/call_stats.c 42;" d file: URI_STATIC_GET stat/spec_stats.c 50;" d file: VAR stat/stats.h 31;" d VARIABLE httperf.h /^ VARIABLE, \/* allows varying input load *\/$/;" e enum:Dist_Type VARIABLE_EXP httperf.h /^ VARIABLE_EXP, \/* varying input load with exponential distribution *\/$/;" e enum:Dist_Type VERSION httperf.h 36;" d WHEEL_SIZE timer.c 36;" d file: WSESSLOG_HEADERS gen/videosesslog.c 91;" d file: _ lib/getopt.c 88;" d file: _ lib/getopt.c 90;" d file: _CALL_STATS_H_ stat/call_stats.h 26;" d _GETOPT_H lib/getopt.h 23;" d _NO_PROTO lib/getopt.c 30;" d file: _WSESSLOG_H_ gen/videosesslog.h 26;" d __BIG_FD_SETSIZE core.h 32;" d __BIG_NFDBITS core.h 33;" d _doprnt configure /^_doprnt();$/;" f _getopt_initialize lib/getopt.c /^_getopt_initialize (optstring)$/;" f file: _getopt_internal lib/getopt.c /^_getopt_internal (argc, argv, optstring, longopts, longind, long_only)$/;" f action event.c /^static Event_Action action[EV_NUM_EVENT_TYPES] = {{0, }};$/;" v file: added_to_epoll conn.h /^ int added_to_epoll; \/* has the sd been added to epoll event set? *\/$/;" m struct:Conn additional_header httperf.h /^ const char *additional_header; \/* additional request header(s) *\/$/;" m struct:Cmdline_Params all_conns_issued stat/basic.c /^ u_int all_conns_issued; \/* total # of connections issued *\/$/;" m struct:__anon13 file: all_footer_bytes_received stat/basic.c /^ u_wide all_footer_bytes_received; \/* sum of all footer bytes *\/$/;" m struct:__anon13 file: all_hdr_bytes_received stat/basic.c /^ u_wide all_hdr_bytes_received; \/* sum of all header bytes *\/$/;" m struct:__anon13 file: all_lifetime_max stat/basic.c /^ Time all_lifetime_max; \/* maximum connection lifetime *\/$/;" m struct:__anon13 file: all_lifetime_min stat/basic.c /^ Time all_lifetime_min; \/* minimum connection lifetime *\/$/;" m struct:__anon13 file: all_lifetime_sum stat/basic.c /^ Time all_lifetime_sum; \/* sum of connection lifetimes *\/$/;" m struct:__anon13 file: all_lifetime_sum2 stat/basic.c /^ Time all_lifetime_sum2; \/* sum of connection lifetimes squared *\/$/;" m struct:__anon13 file: all_lifetime_sum_notm stat/basic.c /^ Time all_lifetime_sum_notm; \/* sum of conn lifetimes for conns that don't time out *\/$/;" m struct:__anon13 file: all_lifetime_sum_tm stat/basic.c /^ Time all_lifetime_sum_tm; \/* sum of conn lifetimes for conns that do time out *\/$/;" m struct:__anon13 file: all_no_timeout_replies stat/basic.c /^ int all_no_timeout_replies; \/* num replies recvd from conns tha did not time out *\/$/;" m struct:__anon13 file: all_num_lifetimes stat/basic.c /^ u_int all_num_lifetimes;$/;" m struct:__anon13 file: all_reply_bytes_received stat/basic.c /^ u_wide all_reply_bytes_received; \/* sum of all data bytes *\/$/;" m struct:__anon13 file: all_timeout_replies stat/basic.c /^ int all_timeout_replies; \/* num replies recvd from conns that eventually timed out *\/$/;" m struct:__anon13 file: alloced_sd_to_conn core.c /^static int min_sd = 0x7fffffff, max_sd = 0, alloced_sd_to_conn = 0;$/;" v file: arg event.c /^ Any_Type arg;$/;" m struct:Event_Action::closure file: arg event.h /^ Any_Type arg;$/;" m struct:Event arg gen/rate.h /^ Any_Type arg;$/;" m struct:Rate_Generator arg timer.h /^ Any_Type arg;$/;" m struct:Timer basic call.h /^ basic;$/;" m struct:Call typeref:struct:Call::__anon1 basic conn.h /^ basic; \/* maintained by stat\/stats_basic.c *\/$/;" m struct:Conn typeref:struct:Conn::__anon4 basic stat/basic.c /^basic;$/;" v typeref:struct:__anon13 file: big_fd_set core.h /^} big_fd_set;$/;" t typeref:struct:__anon5 bindir Makefile /^bindir = ${exec_prefix}\/bin$/;" m bindir gen/Makefile /^bindir = ${exec_prefix}\/bin$/;" m bindir lib/Makefile /^bindir = ${exec_prefix}\/bin$/;" m bindir stat/Makefile /^bindir = ${exec_prefix}\/bin$/;" m birth_time stat/sess_stat.c /^ Time birth_time; \/* when this session got created *\/$/;" m struct:Sess_Private_Data file: buf core.c /^char buf[1048576];$/;" v buf gen/wsesspage.c /^ char buf[1024];$/;" m struct:Call_Private_Data file: buf_len gen/wsesspage.c /^ int buf_len;$/;" m struct:Call_Private_Data file: buf_size stat/call_stats.c /^int buf_size = 0; $/;" v build_fsize stat/call_stats.c /^void build_fsize ()$/;" f build_request_mix_cdf gen/videosesslog.c /^build_request_mix_cdf(void)$/;" f file: burst gen/videosesslog.c /^struct burst$/;" s file: burst_len httperf.h /^ int burst_len; \/* # of calls to burst back-to-back *\/$/;" m struct:Cmdline_Params bytes_received stat/basic.c /^static u_wide bytes_received; \/* number of bytes received in this interval *\/$/;" v file: bytes_recvd stat/spec_stats.c /^ int bytes_recvd; \/* Number of bytes received over all requests *\/$/;" m struct:__anon17 file: bytes_recvd stat/spec_stats.c /^ unsigned int bytes_recvd; \/* Number of bytes recv'd when files of this type were requested *\/$/;" m struct:__anon16 file: bytes_reqd stat/spec_stats.c /^ int bytes_reqd; \/* Number of bytes requested over all requests *\/$/;" m struct:__anon17 file: c httperf.h /^ char c;$/;" m union:__anon8 c_byte_rate stat/call_stats.c /^ double c_byte_rate; \/* rate of receiving bytes *\/$/;" m struct:__anon14 file: c_bytes_recvd stat/call_stats.c /^ int c_bytes_recvd; \/* bytes received *\/$/;" m struct:__anon14 file: c_call_id stat/call_stats.c /^ u_long c_call_id; \/* call id *\/$/;" m struct:__anon14 file: c_conn_id stat/call_stats.c /^ u_long c_conn_id; \/* connection id *\/$/;" m struct:__anon14 file: c_conn_time stat/call_stats.c /^ double c_conn_time; \/* time to connect *\/$/;" m struct:__anon14 file: c_name stat/call_stats.c /^ char c_name[URI_SIZE]; \/* file name *\/$/;" m struct:__anon14 file: c_perc_recvd stat/call_stats.c /^ double c_perc_recvd; \/* percentage of bytes received *\/$/;" m struct:__anon14 file: c_resp_time stat/call_stats.c /^ double c_resp_time; \/* time to receive *\/$/;" m struct:__anon14 file: c_size stat/call_stats.c /^ int c_size; \/* file size *\/$/;" m struct:__anon14 file: c_status stat/call_stats.c /^ int c_status; \/* HTTP status *\/$/;" m struct:__anon14 file: c_time_lim stat/call_stats.c /^ double c_time_lim; \/* time limit *\/$/;" m struct:__anon14 file: c_timeout stat/call_stats.c /^ int c_timeout; \/* timed out? *\/$/;" m struct:__anon14 file: c_total_time stat/call_stats.c /^ double c_total_time; \/*total time *\/$/;" m struct:__anon14 file: call gen/session.c /^ Call *call[MAX_PIPED];$/;" m struct:Sess_Private_Data::Conn_Info file: call_append_request_header call.c /^call_append_request_header (Call *c, const char *hdr, size_t len)$/;" f call_created gen/misc.c /^call_created (Event_Type et, Object *obj, Any_Type reg_arg, Any_Type arg)$/;" f file: call_data stat/call_stats.c /^} call_data;$/;" t typeref:struct:__anon14 file: call_dec_ref call.h 127;" d call_deinit call.c /^call_deinit (Call *call)$/;" f call_destroyed gen/call_seq.c /^call_destroyed (Event_Type et, Call *call)$/;" f file: call_destroyed gen/videosesslog.c /^call_destroyed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)$/;" f file: call_destroyed gen/wsess.c /^call_destroyed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)$/;" f file: call_destroyed gen/wsesspage.c /^call_destroyed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)$/;" f file: call_destroyed stat/print_reply.c /^call_destroyed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)$/;" f file: call_done gen/call_seq.c /^call_done (Event_Type et, Call *call)$/;" f file: call_done gen/session.c /^call_done (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)$/;" f file: call_done stat/sess_stat.c /^call_done (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)$/;" f file: call_h call.h 25;" d call_inc_ref call.h 126;" d call_init call.c /^call_init (Call *c)$/;" f call_issue gen/sess_cookie.c /^call_issue (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)$/;" f file: call_method_name gen/videosesslog.c /^static const char *call_method_name[] =$/;" v file: call_new call.h 125;" d call_private_data_offset gen/sess_cookie.c /^static size_t call_private_data_offset = -1;$/;" v file: call_private_data_offset gen/session.c /^static size_t call_private_data_offset = -1;$/;" v file: call_private_data_offset gen/uri_wset.c /^static size_t call_private_data_offset;$/;" v file: call_private_data_offset gen/wsesspage.c /^static size_t call_private_data_offset;$/;" v file: call_private_data_offset stat/print_reply.c /^static size_t call_private_data_offset = -1;$/;" v file: call_recv_data gen/wsesspage.c /^call_recv_data (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)$/;" f file: call_recv_hdr gen/sess_cookie.c /^call_recv_hdr (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)$/;" f file: call_recv_hdr gen/wsesspage.c /^call_recv_hdr (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)$/;" f file: call_response_sum stat/basic.c /^ Time call_response_sum; \/* sum of response times *\/$/;" m struct:__anon13 file: call_seq gen/call_seq.c /^Load_Generator call_seq =$/;" v call_set_contents call.h 161;" d call_set_location call.h 145;" d call_set_method call.h 137;" d call_set_uri call.h 153;" d call_set_version call.h 135;" d call_stats httperf.h /^ int call_stats; \/* Should we gather call specific statistics? *\/$/;" m struct:Cmdline_Params call_stats stat/call_stats.c /^call_data *call_stats;$/;" v call_stats_file httperf.h /^ char *call_stats_file; \/* file containing file sizes used for call_stats *\/$/;" m struct:Cmdline_Params call_stats_init stat/call_stats.c /^void call_stats_init()$/;" f call_xfer_sum stat/basic.c /^ Time call_xfer_sum; \/* sum of response times *\/$/;" m struct:__anon13 file: ci gen/session.c /^ struct Conn_Info *ci; \/* pointer to relevant conn-info *\/$/;" m struct:Conn_Private_Data typeref:struct:Conn_Private_Data::Conn_Info file: classify_uri stat/spec_stats.c /^classify_uri(char *uri)$/;" f client httperf.h /^ client;$/;" m struct:Cmdline_Params typeref:struct:Cmdline_Params::__anon9 close_with_reset httperf.h /^ int close_with_reset; \/* close connections with TCP RESET? *\/$/;" m struct:Cmdline_Params closure event.c /^ closure[MAX_NUM_OPS];$/;" m struct:Event_Action typeref:struct:Event_Action::closure file: closure event.c /^ struct closure$/;" s struct:Event_Action file: conn call.h /^ struct Conn *conn;$/;" m struct:Call typeref:struct:Call::Conn conn gen/session.c /^ Conn *conn; \/* connection or NULL *\/$/;" m struct:Sess_Private_Data::Conn_Info file: conn_close stat/basic.c /^conn_close(Event_Type et, Object *obj, Any_Type reg_arg, Any_Type call_arg)$/;" f file: conn_connect_sum stat/basic.c /^ Time conn_connect_sum; \/* sum of connect times *\/$/;" m struct:__anon13 file: conn_connected gen/call_seq.c /^conn_connected (Event_Type et, Conn *conn)$/;" f file: conn_connected gen/session.c /^conn_connected (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)$/;" f file: conn_connected stat/basic.c /^conn_connected (Event_Type et, Object *obj, Any_Type reg_arg,$/;" f file: conn_connected stat/sess_stat.c /^conn_connected (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)$/;" f file: conn_connecting stat/basic.c /^conn_connecting (Event_Type et, Object *obj, Any_Type reg_arg, Any_Type c_arg)$/;" f file: conn_created stat/basic.c /^conn_created (Event_Type et, Object *obj, Any_Type reg_arg, Any_Type c_arg)$/;" f file: conn_dec_ref conn.h 132;" d conn_deinit conn.c /^conn_deinit (Conn *conn)$/;" f conn_destroyed stat/basic.c /^conn_destroyed (Event_Type et, Object *obj, Any_Type reg_arg, Any_Type c_arg)$/;" f file: conn_fail stat/basic.c /^conn_fail (Event_Type et, Object *obj, Any_Type reg_arg, Any_Type call_arg)$/;" f file: conn_failed gen/session.c /^conn_failed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)$/;" f file: conn_failure core.c /^conn_failure (Conn *s, int err)$/;" f file: conn_h conn.h 25;" d conn_inc_ref conn.h 131;" d conn_info gen/session.c /^ conn_info[MAX_CONN];$/;" m struct:Sess_Private_Data typeref:struct:Sess_Private_Data::Conn_Info file: conn_init conn.c /^conn_init (Conn *conn)$/;" f conn_lifetime_hist stat/basic.c /^ u_int conn_lifetime_hist[NUM_BINS]; \/* histogram of connection lifetimes *\/$/;" m struct:__anon13 file: conn_lifetime_max stat/basic.c /^ Time conn_lifetime_max; \/* maximum connection lifetime *\/$/;" m struct:__anon13 file: conn_lifetime_min stat/basic.c /^ Time conn_lifetime_min; \/* minimum connection lifetime *\/$/;" m struct:__anon13 file: conn_lifetime_sum stat/basic.c /^ Time conn_lifetime_sum; \/* sum of connection lifetimes *\/$/;" m struct:__anon13 file: conn_lifetime_sum2 stat/basic.c /^ Time conn_lifetime_sum2; \/* sum of connection lifetimes squared *\/$/;" m struct:__anon13 file: conn_lifetime_sum_notm stat/basic.c /^ Time conn_lifetime_sum_notm; \/* sum of conn lifetimes for conns that don't time out *\/$/;" m struct:__anon13 file: conn_lifetime_sum_tm stat/basic.c /^ Time conn_lifetime_sum_tm; \/* sum of conn lifetimes for conns that do time out *\/$/;" m struct:__anon13 file: conn_new conn.h 130;" d conn_private_data_offset gen/call_seq.c /^static size_t conn_private_data_offset;$/;" v file: conn_private_data_offset gen/session.c /^static size_t conn_private_data_offset = -1;$/;" v file: conn_rate gen/conn_rate.c /^Load_Generator conn_rate =$/;" v conn_timeout core.c /^conn_timeout (Timer *t, Any_Type arg)$/;" f file: conn_timeout gen/session.c /^conn_timeout (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)$/;" f file: conn_timeout stat/basic.c /^conn_timeout (Event_Type et, Object *obj, Any_Type reg_arg, Any_Type call_arg)$/;" f file: const lib/getopt.c 44;" d file: const lib/getopt1.c 33;" d file: content call.h /^ char * content; \/* Used for reply-verification only *\/$/;" m struct:Call::__anon3 content_bytes call.h /^ size_t content_bytes; \/* # of reply data bytes received so far *\/$/;" m struct:Call::__anon3 content_length conn.h /^ size_t content_length; \/* content length (or INF if unknown) *\/$/;" m struct:Conn contents gen/videosesslog.c /^ char *contents;$/;" m struct:req file: contents_len gen/videosesslog.c /^ int contents_len;$/;" m struct:req file: cookie gen/sess_cookie.c /^ char cookie[MAX_COOKIE_LEN];$/;" m struct:Call_Private_Data file: cookie gen/sess_cookie.c /^ char cookie[MAX_COOKIE_LEN];$/;" m struct:Sess_Private_Data file: cookie gen/videosesslog.c /^ char *cookie;$/;" m struct:req file: cookie_len gen/sess_cookie.c /^ size_t cookie_len;$/;" m struct:Sess_Private_Data file: cookie_len gen/videosesslog.c /^ int cookie_len;$/;" m struct:req file: cookie_present gen/sess_cookie.c /^ u_int cookie_present; \/* non-zero if cookie has been set already *\/$/;" m struct:Call_Private_Data file: core_addr_intern core.c /^core_addr_intern (const char *server, size_t server_len, int port)$/;" f core_close core.c /^core_close (Conn *conn)$/;" f core_connect core.c /^core_connect (Conn *s)$/;" f core_exit core.c /^core_exit (void)$/;" f core_h core.h 25;" d core_init core.c /^core_init (void)$/;" f core_loop core.c /^core_loop (void)$/;" f core_loop_epoll core.c /^core_loop_epoll (void)$/;" f file: core_loop_handle_socket core.c /^core_loop_handle_socket (int sd, int is_readable, int is_writable)$/;" f file: core_loop_select core.c /^core_loop_select (void)$/;" f core_loop_timer_start core.c /^ static Time core_loop_timer_start;$/;" v file: core_send core.c /^core_send (Conn *conn, Call *call)$/;" f core_ssl_connect core.c /^core_ssl_connect (Conn *s)$/;" f count stat/spec_stats.c /^ int count; \/* Number of sessions of this length that were initiated *\/$/;" m struct:__anon17 file: cpu_mask httperf.h /^ unsigned long cpu_mask; \/* mask of schedulable CPUs (if supported) *\/$/;" m struct:Cmdline_Params create_conn gen/session.c /^create_conn (Sess *sess, struct Conn_Info *ci)$/;" f file: cur_missed_bur gen/videosesslog.c /^ BURST *cur_missed_bur;$/;" m struct:Sess_Private_Data file: cur_missed_req gen/videosesslog.c /^ REQ *cur_missed_req;$/;" m struct:Sess_Private_Data file: cur_port httperf.h /^ int cur_port;$/;" m struct:Cmdline_Params::__anon10 curr timer.c /^static Timer_Queue wheel[WHEEL_SIZE], *curr = 0;$/;" v file: current_burst gen/videosesslog.c /^ BURST *current_burst; \/* the current burst we're working on *\/$/;" m struct:Sess_Private_Data file: current_rate gen/rate.c /^int current_rate = 0;$/;" v current_req gen/videosesslog.c /^ REQ *current_req; \/* the current request we're working on *\/$/;" m struct:Sess_Private_Data file: cvp httperf.h /^ const void *cvp;$/;" m union:__anon8 d httperf.h /^ double d;$/;" m union:__anon8 data_blank stat/call_stats.c /^ char *data_blank; \/* used for printing a blank data entry, use with hdr_frmt *\/$/;" m struct:print_stats file: data_frmt stat/call_stats.c /^ char *data_frmt;\/* format used for data, should be the same width as above *\/$/;" m struct:print_stats file: debug_level httperf.c /^int debug_level;$/;" v delta timer.h /^ u_long delta;$/;" m struct:Timer destroyed gen/conn_rate.c /^destroyed (void)$/;" f file: dist httperf.h /^ Dist_Type dist; \/* interarrival distribution *\/$/;" m struct:Rate_Info do_recv core.c /^do_recv (Conn *s)$/;" f file: do_send core.c /^do_send (Conn *conn)$/;" f file: done gen/rate.c /^done (Event_Type type, Object *obj, Any_Type reg_arg, Any_Type call_arg)$/;" f file: done gen/rate.h /^ int done;$/;" m struct:Rate_Generator done timer.c /^done (Timer *t)$/;" f file: done_with_reply_hdr stat/print_reply.c /^ int done_with_reply_hdr; \/* are we done printing reply header? *\/$/;" m struct:Call_Private_Data file: dump httperf.h /^ void (*dump) (void);$/;" m struct:Stat_Collector dump stat/basic.c /^dump (void)$/;" f file: dump stat/sess_stat.c /^dump (void)$/;" f file: dump_stats httperf.c /^dump_stats (Timer *t, Any_Type regarg)$/;" f file: dump_stats stat/basic.c /^dump_stats (Event_Type et, Object *obj, Any_Type req_arg, Any_Type call_arg)$/;" f file: dump_stats stat/sess_stat.c /^dump_stats (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)$/;" f file: dump_stats_start httperf.c /^Time dump_stats_start;$/;" v duration httperf.h /^ Time duration[NUM_RATES];$/;" m struct:Rate_Info duration_in_current_rate gen/rate.c /^Time duration_in_current_rate = 0;$/;" v epoll_events core.c /^static struct epoll_event *epoll_events;$/;" v typeref:struct:epoll_event file: epoll_fd core.c /^static int epoll_fd;$/;" v file: epoll_max_events core.c /^static int epoll_max_events;$/;" v file: epoll_timeout core.c /^static int epoll_timeout;$/;" v file: err_report_init stat/basic.c /^err_report_init(void)$/;" f file: errno_errs_reported stat/basic.c /^unsigned int *errno_errs_reported = 0;$/;" v event_h event.h 26;" d event_name event.c /^static const char * const event_name[EV_NUM_EVENT_TYPES] =$/;" v file: event_register_handler event.c /^event_register_handler (Event_Type et, Event_Handler handler, Any_Type arg)$/;" f event_signal event.c /^event_signal (Event_Type type, Object *obj, Any_Type arg)$/;" f exchange lib/getopt.c /^exchange (argv)$/;" f file: expire ttest.c /^expire (struct Timer *t)$/;" f extra gen/misc.c /^static const char *extra;$/;" v file: extra_hdrs gen/videosesslog.c /^ char extra_hdrs[16384]; \/* plenty for "Content-length: 1234567890" + custom headers *\/$/;" m struct:req file: extra_hdrs gen/videosesslog.c /^ char extra_hdrs[50]; \/* plenty for "Content-length: 1234567890" *\/$/;" m struct:req file: extra_hdrs_len gen/videosesslog.c /^ int extra_hdrs_len;$/;" m struct:req file: extra_len gen/misc.c /^static size_t extra_len;$/;" v file: f httperf.h /^ float f;$/;" m union:__anon8 f_size stat/call_stats.c /^ int f_size;$/;" m struct:f_uri_size file: f_sizes stat/call_stats.c /^struct f_uri_size *f_sizes;$/;" v typeref:struct:f_uri_size f_uri stat/call_stats.c /^ char f_uri[URI_SIZE];$/;" m struct:f_uri_size file: f_uri_size stat/call_stats.c /^struct f_uri_size {$/;" s file: failed sess.h /^ u_int failed : 1; \/* did session fail? *\/$/;" m struct:Sess failtime_sum stat/sess_stat.c /^ Time failtime_sum;$/;" m struct:__anon15 file: failure_status httperf.h /^ int failure_status; \/* status code that should be considered failure *\/$/;" m struct:Cmdline_Params fbase gen/uri_wlog.c /^static char *fbase, *fend, *fcurrent;$/;" v file: fcurrent gen/uri_wlog.c /^static char *fbase, *fend, *fcurrent;$/;" v file: fds_bits core.h /^ unsigned long fds_bits[__BIG_FD_SETSIZE \/ (8 * sizeof (unsigned long))];$/;" m struct:__anon5 fend gen/uri_wlog.c /^static char *fbase, *fend, *fcurrent;$/;" v file: fetch_uri gen/wsesspage.c /^fetch_uri (Sess *sess, Sess_Private_Data *priv, Call_Private_Data *cpriv,$/;" f file: file httperf.h /^ char file[MAX_LOG_FILES][1024]; \/* File names of session logs *\/$/;" m struct:Cmdline_Params::__anon11 file_num gen/uri_wset.c /^static unsigned file_num;$/;" v file: file_size call.h /^ int file_size;$/;" m struct:Call file_size gen/videosesslog.c /^ int file_size;$/;" m struct:req file: file_sizes stat/spec_stats.c /^int file_sizes[NUM_SPEC_FILES] = {$/;" v file_stats stat/spec_stats.c /^spec_file_data file_stats[NUM_SPEC_FILES];$/;" v find_stack_direction configure /^find_stack_direction ()$/;" f first_nonopt lib/getopt.c /^static int first_nonopt;$/;" v file: flag lib/getopt.h /^ int *flag;$/;" m struct:option flush_print_buf stat/print_reply.c /^flush_print_buf (Call *call, const char *prefix)$/;" f file: footer_bytes call.h /^ size_t footer_bytes; \/* # of footer bytes received so far *\/$/;" m struct:Call::__anon3 footer_bytes_received stat/basic.c /^ u_wide footer_bytes_received; \/* sum of all footer bytes *\/$/;" m struct:__anon13 file: fqdname conn.h /^ const char *fqdname; \/* fully qualified server name (or 0) *\/$/;" m struct:Conn fqdname_len conn.h /^ size_t fqdname_len;$/;" m struct:Conn free_list object.c /^static struct free_list_el *free_list[OBJ_NUM_TYPES];$/;" v typeref:struct:free_list_el file: free_list_el object.c /^struct free_list_el$/;" s file: func timer.h /^ Timer_Callback func;$/;" m struct:Timer get_call_next_id call.c /^int get_call_next_id ()$/;" f get_call_total_conn_time stat/call_stats.c /^double get_call_total_conn_time( Call *cur_call )$/;" f get_f_size stat/call_stats.c /^int get_f_size (char uri[URI_SIZE])$/;" f get_file_index stat/spec_stats.c /^get_file_index(char *str)$/;" f get_index stat/call_stats.c /^int get_index (Call * c)$/;" f get_line http.c /^get_line (Call *c, char **bufp, size_t *buf_lenp)$/;" f file: get_next_missed_size gen/videosesslog.c /^get_next_missed_size(Conn *conn)$/;" f get_next_missed_timelimit gen/videosesslog.c /^get_next_missed_timelimit(Conn *conn)$/;" f get_next_missed_uri gen/videosesslog.c /^get_next_missed_uri(Conn *conn)$/;" f get_spec_index stat/spec_stats.c /^int get_spec_index( Call * c ) {$/;" f getopt lib/getopt.c /^getopt (argc, argv, optstring)$/;" f getopt_long lib/getopt1.c /^getopt_long (argc, argv, options, long_options, opt_index)$/;" f getopt_long_only lib/getopt1.c /^getopt_long_only (argc, argv, options, long_options, opt_index)$/;" f getpid lib/getopt.c 80;" d file: has_arg lib/getopt.h /^ int has_arg;$/;" m struct:option has_body conn.h /^ u_int has_body : 1; \/* does reply have a body? *\/$/;" m struct:Conn hash_code core.c /^hash_code (const char *server, size_t server_len, int port)$/;" f file: hash_enter core.c /^hash_enter (const char *server, size_t server_len, int port,$/;" f file: hash_entry core.c /^struct hash_entry$/;" s file: hash_lookup core.c /^hash_lookup (const char *server, size_t server_len, int port)$/;" f hash_table core.c /^hash_table[HASH_TABLE_SIZE];$/;" v typeref:struct:hash_entry hdr stat/call_stats.c /^ char *hdr; \/* header *\/$/;" m struct:print_stats file: hdr_bytes_received stat/basic.c /^ u_wide hdr_bytes_received; \/* sum of all header bytes *\/$/;" m struct:__anon13 file: hdr_frmt stat/call_stats.c /^ char *hdr_frmt; \/* format used for header and units*\/$/;" m struct:print_stats file: header_bytes call.h /^ size_t header_bytes; \/* # of header bytes received so far *\/$/;" m struct:Call::__anon3 hog httperf.h /^ int hog; \/* client may hog as much resources as possible *\/$/;" m struct:Cmdline_Params hostname conn.h /^ const char *hostname; \/* server's hostname (or 0 for default) *\/$/;" m struct:Conn hostname core.c /^ const char *hostname;$/;" m struct:hash_entry file: hostname_len conn.h /^ size_t hostname_len;$/;" m struct:Conn http10req core.c /^ static char http10req[] =$/;" v file: http10req_nohost core.c /^ static char http10req_nohost[] =$/;" v file: http11req core.c /^ static char http11req[] =$/;" v file: http11req_nohost core.c /^ static char http11req_nohost[] =$/;" v file: http_h http.h 26;" d http_process_reply_bytes http.c /^http_process_reply_bytes (Call *c, char **bufp, size_t *buf_lenp)$/;" f http_version gen/videosesslog.c /^ int http_version; \/* HTTP version number *\/$/;" m struct:Sess_Private_Data file: http_version httperf.h /^ int http_version; \/* (default) HTTP protocol version *\/$/;" m struct:Cmdline_Params httperf_errs_reported stat/basic.c /^unsigned int *httperf_errs_reported = 0;$/;" v httperf_h httperf.h 26;" d i httperf.h /^ int i;$/;" m union:__anon8 iat httperf.h /^ Time iat[NUM_RATES];$/;" m struct:Rate_Info id call.h /^ u_long id; \/* unique id *\/$/;" m struct:Call id conn.h /^ u_long id;$/;" m struct:Conn id httperf.h /^ u_int id;$/;" m struct:Cmdline_Params::__anon9 id_hdr call.h /^ char id_hdr[28]; $/;" m struct:Call idle_conns httperf.h /^ int idle_conns; \/* idle # of connections per session *\/$/;" m struct:Cmdline_Params idleconn httperf.h /^ char* idleconn; \/* idleconn binary path *\/$/;" m struct:Cmdline_Params inc_call_next_id call.c /^int inc_call_next_id(int n)$/;" f init gen/call_seq.c /^init (void)$/;" f file: init gen/conn_rate.c /^init (void)$/;" f file: init gen/misc.c /^init (void)$/;" f file: init gen/sess_cookie.c /^init (void)$/;" f file: init gen/uri_fixed.c /^init (void)$/;" f file: init gen/uri_wset.c /^init (void)$/;" f file: init gen/videosesslog.c /^init (void)$/;" f file: init gen/wsess.c /^init (void)$/;" f file: init gen/wsesspage.c /^init (void)$/;" f file: init httperf.h /^ void (*init) (void);$/;" m struct:Load_Generator init httperf.h /^ void (*init) (void);$/;" m struct:Stat_Collector init stat/basic.c /^init (void)$/;" f file: init stat/print_reply.c /^init (void)$/;" f file: init stat/sess_stat.c /^init (void)$/;" f file: init_epoll core.c /^init_epoll (void)$/;" f file: init_wlog gen/uri_wlog.c /^init_wlog (void)$/;" f interested_in_reading core.c /^interested_in_reading (Conn *s)$/;" f file: interested_in_reading_no_timeout core.c /^interested_in_reading_no_timeout (Conn *s)$/;" f file: interested_in_writing core.c /^interested_in_writing (Conn *s)$/;" f file: iov call.h /^ struct iovec iov[IE_LEN];$/;" m struct:Call::__anon2 typeref:struct:Call::__anon2::iovec iov_index call.h /^ int iov_index; \/* first iov element that has data *\/$/;" m struct:Call::__anon2 iov_saved call.h /^ struct iovec iov_saved; \/* saved copy of iov[iov_index] *\/$/;" m struct:Call::__anon2 typeref:struct:Call::__anon2::iovec is_chunked conn.h /^ u_int is_chunked : 1; \/* is the reply chunked? *\/$/;" m struct:Conn is_connected gen/session.c /^ u_int is_connected : 1; \/* is connection ready for use? *\/$/;" m struct:Sess_Private_Data::Conn_Info file: is_stable conn.h /^ u_int is_stable; \/* true when not ramping up or ramping down *\/$/;" m struct:Conn::__anon4 is_stable stat/basic.c /^ u_int is_stable; \/* true when not ramping up or ramping down *\/$/;" m struct:__anon13 file: is_successful gen/session.c /^ u_int is_successful : 1; \/* got at least one reply on this conn? *\/$/;" m struct:Sess_Private_Data::Conn_Info file: issue_calls gen/call_seq.c /^issue_calls (Conn *conn)$/;" f file: issue_calls gen/videosesslog.c /^issue_calls (Sess *sess, Sess_Private_Data *priv)$/;" f file: issue_calls gen/wsess.c /^issue_calls (Sess *sess, Sess_Private_Data *priv)$/;" f file: issue_calls gen/wsesspage.c /^issue_calls (Sess *sess, Sess_Private_Data *priv)$/;" f file: iteration core.c /^static int iteration;$/;" v file: l httperf.h /^ long l;$/;" m union:__anon8 last_nonopt lib/getopt.c /^static int last_nonopt;$/;" v file: lb_ports httperf.h /^ lb_ports;$/;" m struct:Cmdline_Params typeref:struct:Cmdline_Params::__anon10 ldbg stat/basic.c 75;" d file: ldbg stat/basic.c 84;" d file: len stat/print_reply.c /^ size_t len; \/* current length of line buffer *\/$/;" m struct:Call_Private_Data file: len_hist stat/sess_stat.c /^ u_int *len_hist;$/;" m struct:__anon15 file: len_hist_alloced stat/sess_stat.c /^ u_int len_hist_alloced;$/;" m struct:__anon15 file: lffs core.c /^lffs (long w)$/;" f file: lifetime_sum stat/sess_stat.c /^ Time lifetime_sum;$/;" m struct:__anon15 file: line conn.h /^ struct iovec line; \/* buffer used to parse reply headers *\/$/;" m struct:Conn typeref:struct:Conn::iovec line stat/print_reply.c /^ char *line; \/* line buffer *\/$/;" m struct:Call_Private_Data file: line_buf conn.h /^ char line_buf[MAX_HDR_LINE_LEN]; \/* default line buffer *\/$/;" m struct:Conn local_ip conn.h /^ char local_ip[16]; \/* The local-ip to bind this connection to. *\/$/;" m struct:Conn local_ip gen/videosesslog.c /^ char local_ip[16];$/;" m struct:Sess_Private_Data file: local_ip httperf.h /^ char local_ip[MAX_LOG_FILES][16]; \/* The local-ip addresses to bind to. *\/$/;" m struct:Cmdline_Params::__anon11 local_ip sess.h /^ char local_ip[16];$/;" m struct:Sess longest_session stat/sess_stat.c /^ u_int longest_session;$/;" m struct:__anon15 file: longopts httperf.c /^static struct option longopts[] =$/;" v typeref:struct:option file: main config.guess /^ main()$/;" f main config.guess /^ main ()$/;" f main config.guess /^main ()$/;" f main httperf.c /^main (int argc, char **argv)$/;" f main idleconn.c /^main (int argc, char **argv)$/;" f main lib/getopt.c /^main (argc, argv)$/;" f main lib/getopt1.c /^main (argc, argv)$/;" f main ttest.c /^main (int argc, char **argv)$/;" f make_conn gen/conn_rate.c /^make_conn (Any_Type arg)$/;" f file: mandir Makefile /^mandir = ${prefix}\/man$/;" m mandir gen/Makefile /^mandir = ${prefix}\/man$/;" m mandir lib/Makefile /^mandir = ${prefix}\/man$/;" m mandir stat/Makefile /^mandir = ${prefix}\/man$/;" m max_all_conns stat/basic.c /^ int max_all_conns; \/* max # of concurrent connected connections *\/$/;" m struct:__anon13 file: max_burst_len core.c /^static u_long max_burst_len;$/;" v file: max_connected_conns stat/basic.c /^ int max_connected_conns; \/* max # of concurrent connected connections *\/$/;" m struct:__anon13 file: max_conns httperf.h /^ int max_conns; \/* max # of connections per session *\/$/;" m struct:Cmdline_Params max_conns stat/basic.c /^ u_int max_conns; \/* max # of concurrent connections *\/$/;" m struct:__anon13 file: max_iat httperf.h /^ Time max_iat; \/* max interarrival time (for UNIFORM) *\/$/;" m struct:Rate_Info max_piped httperf.h /^ int max_piped; \/* max # of piped calls per connection *\/$/;" m struct:Cmdline_Params max_qlen gen/session.c /^static size_t max_qlen;$/;" v file: max_sd core.c /^static int min_sd = 0x7fffffff, max_sd = 0, alloced_sd_to_conn = 0;$/;" v file: mean_iat httperf.h /^ Time mean_iat; \/* mean interarrival time *\/$/;" m struct:Rate_Info method gen/videosesslog.c /^ int method;$/;" m struct:req file: method httperf.h /^ const char *method; \/* default call method *\/$/;" m struct:Cmdline_Params method_len gen/misc.c /^static size_t method_len;$/;" v file: min lib/ssl_writev.c 73;" d file: min_iat httperf.h /^ Time min_iat; \/* min interarrival time (for UNIFORM) *\/$/;" m struct:Rate_Info min_sd core.c /^static int min_sd = 0x7fffffff, max_sd = 0, alloced_sd_to_conn = 0;$/;" v file: misc gen/misc.c /^Load_Generator misc =$/;" v miss_prob gen/uri_wset.c /^static double miss_prob;$/;" v file: missing_bytes stat/spec_stats.c /^ int missing_bytes; \/* Number of requests that completed, but had missing bytes *\/$/;" m struct:__anon16 file: my_index lib/getopt.c /^my_index (str, chr)$/;" f file: my_index lib/getopt.c 196;" d file: myaddr core.c /^static struct sockaddr_in myaddr;$/;" v typeref:struct:sockaddr_in file: myport conn.h /^ int myport; \/* local port number or -1 *\/$/;" m struct:Conn name httperf.h /^ const char *name;$/;" m struct:Load_Generator name httperf.h /^ const char *name;$/;" m struct:Stat_Collector name lib/getopt.h /^ const char *name;$/;" m struct:option new_burst gen/videosesslog.c /^new_burst (REQ *r)$/;" f file: new_request gen/videosesslog.c /^new_request (char *uristr)$/;" f file: next conn.h /^ struct Conn *next;$/;" m struct:Conn typeref:struct:Conn::Conn next gen/videosesslog.c /^ BURST *next;$/;" m struct:burst file: next gen/videosesslog.c /^ REQ *next;$/;" m struct:req file: next gen/wsesspage.c /^ struct uri_list *next;$/;" m struct:Sess_Private_Data::uri_list typeref:struct:Sess_Private_Data::uri_list::uri_list file: next object.c /^ struct free_list_el *next;$/;" m struct:free_list_el typeref:struct:free_list_el::free_list_el file: next timer.h /^ struct Timer *next;$/;" m struct:Timer_Queue typeref:struct:Timer_Queue::Timer next_arrival_time_det gen/rate.c /^next_arrival_time_det (Rate_Generator *rg)$/;" f file: next_arrival_time_exp gen/rate.c /^next_arrival_time_exp (Rate_Generator *rg)$/;" f file: next_arrival_time_uniform gen/rate.c /^next_arrival_time_uniform (Rate_Generator *rg)$/;" f file: next_arrival_time_variable gen/rate.c /^next_arrival_time_variable (Rate_Generator *rg)$/;" f file: next_arrival_time_variable_exp gen/rate.c /^next_arrival_time_variable_exp (Rate_Generator *rg)$/;" f file: next_id call.c /^static u_long next_id = 0;$/;" v file: next_interarrival_time gen/rate.h /^ Time (*next_interarrival_time) (struct Rate_Generator *rg);$/;" m struct:Rate_Generator next_session_template gen/videosesslog.c /^ int next_session_template;$/;" m struct:Session_Log_Desc file: next_tick timer.c /^static Time next_tick;$/;" v file: next_time gen/rate.h /^ Time next_time;$/;" m struct:Rate_Generator nextchar lib/getopt.c /^static char *nextchar;$/;" v file: no_argument lib/getopt.h 97;" d no_host_hdr httperf.h /^ int no_host_hdr; \/* don't send Host: header in request *\/$/;" m struct:Cmdline_Params no_op httperf.c /^no_op (void)$/;" f no_timeout_replies stat/basic.c /^ int no_timeout_replies; \/* num replies recvd from conns tha did not time out *\/$/;" m struct:__anon13 file: nonoption_flags lib/getopt.c /^static const char *nonoption_flags;$/;" v file: nonoption_flags_len lib/getopt.c /^static int nonoption_flags_len;$/;" v file: now timer.c /^static Time now;$/;" v file: numRates httperf.h /^ int numRates; \/* number of rates we want to use *\/$/;" m struct:Rate_Info num_active_conns stat/basic.c /^ u_int num_active_conns;$/;" m struct:__anon13 file: num_active_conns stat/basic.c /^static u_int num_active_conns;$/;" v file: num_all_replies stat/basic.c /^ u_int num_all_replies; \/* completion count for all connections *\/$/;" m struct:__anon13 file: num_all_sent stat/basic.c /^ u_int num_all_sent; \/* # of requests sent *\/$/;" m struct:__anon13 file: num_calls conn.h /^ u_int num_calls; \/* # of calls that should be completed *\/$/;" m struct:Conn::__anon4 num_calls gen/call_seq.c /^ int num_calls;$/;" m struct:Conn_Private_Data file: num_calls httperf.h /^ int num_calls; \/* # of calls to generate per connection *\/$/;" m struct:Cmdline_Params num_calls_completed conn.h /^ u_int num_calls_completed; \/* # of calls that completed *\/$/;" m struct:Conn::__anon4 num_calls_completed stat/sess_stat.c /^ u_int num_calls_completed; \/* how many calls completed? *\/$/;" m struct:Sess_Private_Data file: num_calls_destroyed gen/videosesslog.c /^ u_int num_calls_destroyed; \/* # of calls destroyed so far *\/$/;" m struct:Sess_Private_Data file: num_calls_destroyed gen/wsess.c /^ u_int num_calls_destroyed; \/* # of calls destroyed so far *\/$/;" m struct:Sess_Private_Data file: num_calls_in_this_burst gen/videosesslog.c /^ u_int num_calls_in_this_burst; \/* # of calls created for this burst *\/$/;" m struct:Sess_Private_Data file: num_calls_in_this_burst gen/wsess.c /^ u_int num_calls_in_this_burst; \/* # of calls created for this burst *\/$/;" m struct:Sess_Private_Data file: num_calls_target gen/videosesslog.c /^ u_int num_calls_target; \/* total # of calls desired *\/$/;" m struct:Sess_Private_Data file: num_calls_target gen/wsess.c /^ u_int num_calls_target; \/* total # of calls desired *\/$/;" m struct:Sess_Private_Data file: num_client_connected_timeouts stat/basic.c /^ int num_client_connected_timeouts; \/* timeout happened after connection was established *\/$/;" m struct:__anon13 file: num_client_timeouts stat/basic.c /^ u_int num_client_timeouts; \/* # of client timeouts *\/$/;" m struct:__anon13 file: num_client_unconnected_timeouts stat/basic.c /^ int num_client_unconnected_timeouts; \/* timeout happened before connection was established *\/$/;" m struct:__anon13 file: num_clients httperf.h /^ u_int num_clients;$/;" m struct:Cmdline_Params::__anon9 num_closed idleconn.c /^unsigned long num_conn, num_closed;$/;" v num_completed gen/call_seq.c /^ int num_completed;$/;" m struct:Conn_Private_Data file: num_completed stat/sess_stat.c /^ u_int num_completed;$/;" m struct:__anon15 file: num_completed_since_last_sample stat/sess_stat.c /^ u_int num_completed_since_last_sample;$/;" m struct:__anon15 file: num_conn idleconn.c /^unsigned long num_conn, num_closed;$/;" v num_connected_conns stat/basic.c /^ int num_connected_conns; \/* # of concurrent connected connections *\/$/;" m struct:__anon13 file: num_connects stat/basic.c /^ u_int num_connects; \/* # of completed connect()s *\/$/;" m struct:__anon13 file: num_conns httperf.h /^ int num_conns; \/* # of connections to generate *\/$/;" m struct:Cmdline_Params num_conns stat/sess_stat.c /^ u_int num_conns; \/* # of connections on this session *\/$/;" m struct:Sess_Private_Data file: num_conns stat/sess_stat.c /^ u_int num_conns; \/* total # of connections on successful sessions *\/$/;" m struct:__anon15 file: num_conns_destroyed gen/conn_rate.c /^static int num_conns_destroyed;$/;" v file: num_conns_generated gen/conn_rate.c /^static int num_conns_generated;$/;" v file: num_conns_issued stat/basic.c /^ u_int num_conns_issued; \/* total # of connections issued *\/$/;" m struct:__anon13 file: num_created gen/wsesspage.c /^ u_int num_created; \/* # of calls created in this burst *\/$/;" m struct:Sess_Private_Data file: num_destroyed gen/call_seq.c /^ int num_destroyed;$/;" m struct:Conn_Private_Data file: num_destroyed gen/wsesspage.c /^ u_int num_destroyed; \/* # of calls destroyed in this burst *\/$/;" m struct:Sess_Private_Data file: num_extra_hdrs call.h /^ u_int num_extra_hdrs; \/* number of additional headers in use *\/$/;" m struct:Call::__anon2 num_failed stat/sess_stat.c /^ u_int num_failed;$/;" m struct:__anon15 file: num_files stat/call_stats.c /^int num_files;$/;" v num_lifetimes stat/basic.c /^ u_int num_lifetimes;$/;" m struct:__anon13 file: num_logs httperf.h /^ u_int num_logs; \/* # of session logs *\/$/;" m struct:Cmdline_Params::__anon11 num_missed_calls gen/videosesslog.c /^num_missed_calls (Conn *conn)$/;" f num_ops event.c /^ int num_ops;$/;" m struct:Event_Action file: num_other_errors stat/basic.c /^ u_int num_other_errors; \/* # of other errors *\/$/;" m struct:__anon13 file: num_pending gen/session.c /^ u_int num_pending; \/* # of calls pending *\/$/;" m struct:Sess_Private_Data::Conn_Info file: num_ports httperf.h /^ int num_ports;$/;" m struct:Cmdline_Params::__anon10 num_rate_samples stat/sess_stat.c /^ u_int num_rate_samples;$/;" m struct:__anon15 file: num_replies stat/basic.c /^ u_int num_replies[6]; \/* completion count per status class *\/$/;" m struct:__anon13 file: num_replies stat/basic.c /^static u_int num_replies; \/* # of replies received in this interval *\/$/;" v file: num_reply_samples stat/basic.c /^ u_int num_reply_samples;$/;" m struct:__anon13 file: num_reqs gen/videosesslog.c /^ int num_reqs;$/;" m struct:burst file: num_reqs_completed gen/wsesspage.c /^ u_int num_reqs_completed; \/* # of user reqs completed *\/$/;" m struct:Sess_Private_Data file: num_requests sess.h /^ int num_requests; \/* The number of requests in this session*\/$/;" m struct:Sess num_responses stat/basic.c /^ u_int num_responses;$/;" m struct:__anon13 file: num_sent gen/session.c /^ u_int num_sent; \/* # of calls sent so far *\/$/;" m struct:Sess_Private_Data::Conn_Info file: num_sent stat/basic.c /^ u_int num_sent; \/* # of requests sent *\/$/;" m struct:__anon13 file: num_sessions httperf.h /^ u_int num_sessions; \/* # of user-sessions *\/$/;" m struct:Cmdline_Params::__anon11 num_sessions_destroyed gen/videosesslog.c /^static int num_sessions_destroyed;$/;" v file: num_sessions_destroyed gen/wsess.c /^static int num_sessions_destroyed;$/;" v file: num_sessions_destroyed gen/wsesspage.c /^static int num_sessions_destroyed;$/;" v file: num_sessions_generated gen/videosesslog.c /^static int num_sessions_generated;$/;" v file: num_sessions_generated gen/wsess.c /^static int num_sessions_generated;$/;" v file: num_sessions_generated gen/wsesspage.c /^static int num_sessions_generated;$/;" v file: num_sock_addrinuse stat/basic.c /^ u_int num_sock_addrinuse; \/* # of EADDRINUSE *\/$/;" m struct:__anon13 file: num_sock_addrunavail stat/basic.c /^ u_int num_sock_addrunavail;\/* # of EADDRNOTAVAIL *\/$/;" m struct:__anon13 file: num_sock_fdunavail stat/basic.c /^ u_int num_sock_fdunavail; \/* # of times out of filedescriptors *\/$/;" m struct:__anon13 file: num_sock_ftabfull stat/basic.c /^ u_int num_sock_ftabfull; \/* # of times file table was full *\/$/;" m struct:__anon13 file: num_sock_refused stat/basic.c /^ u_int num_sock_refused; \/* # of ECONNREFUSED *\/$/;" m struct:__anon13 file: num_sock_reset stat/basic.c /^ u_int num_sock_reset; \/* # of ECONNRESET *\/$/;" m struct:__anon13 file: num_sock_timeouts stat/basic.c /^ u_int num_sock_timeouts; \/* # of ETIMEDOUT *\/$/;" m struct:__anon13 file: num_templates gen/videosesslog.c /^ int num_templates;$/;" m struct:Session_Log_Desc file: num_total_all_conns stat/basic.c /^ int num_total_all_conns;$/;" m struct:__anon13 file: num_total_connected_conns stat/basic.c /^ int num_total_connected_conns;$/;" m struct:__anon13 file: obj call.h /^ Object obj;$/;" m struct:Call obj conn.h /^ Object obj;$/;" m struct:Conn obj event.h /^ Object *obj;$/;" m struct:Event obj sess.h /^ Object obj;$/;" m struct:Sess object_dec_ref object.c /^object_dec_ref (Object *obj)$/;" f object_destroy object.c /^object_destroy (Object *obj)$/;" f file: object_expand object.c /^object_expand (Object_Type type, size_t size)$/;" f object_h object.h 25;" d object_inc_ref object.h 63;" d object_is_call object.h 29;" d object_is_call object.h 33;" d object_is_conn object.h 28;" d object_is_conn object.h 32;" d object_is_sess object.h 30;" d object_is_sess object.h 34;" d object_new object.c /^object_new (Object_Type type)$/;" f object_type_size httperf.c /^size_t object_type_size[OBJ_NUM_TYPES];$/;" v op event.c /^ Event_Handler op;$/;" m struct:Event_Action::closure file: optarg lib/getopt.c /^char *optarg = NULL;$/;" v opterr lib/getopt.c /^int opterr = 1;$/;" v optind lib/getopt.c /^int optind = 0;$/;" v option lib/getopt.h /^struct option$/;" s optional_argument lib/getopt.h 99;" d optopt lib/getopt.c /^int optopt = '?';$/;" v ordering lib/getopt.c /^} ordering;$/;" v typeref:enum:__anon12 file: output_log httperf.h /^ char* output_log;$/;" m struct:Cmdline_Params pace_requests gen/videosesslog.c /^ int pace_requests;$/;" m struct:burst file: panic httperf.c /^panic (const char *msg, ...)$/;" f param httperf.c /^Cmdline_Params param;$/;" v parse_config gen/videosesslog.c /^parse_config (void)$/;" f file: parse_data http.c /^parse_data (Call *c, char **bufp, size_t *buf_lenp)$/;" f file: parse_footers http.c /^parse_footers (Call *c, char **bufp, size_t *buf_lenp)$/;" f file: parse_headers http.c /^parse_headers (Call *c, char **bufp, size_t *buf_lenp)$/;" f file: parse_status_line http.c /^parse_status_line (Call *c, char **bufp, size_t *buf_lenp)$/;" f file: perf_sample httperf.c /^perf_sample (Timer *t, Any_Type regarg)$/;" f file: perf_sample stat/basic.c /^perf_sample (Event_Type et, Object *obj, Any_Type reg_arg, Any_Type call_arg)$/;" f file: perf_sample stat/sess_stat.c /^perf_sample (Event_Type et, Object *obj, Any_Type reg_arg, Any_Type call_arg)$/;" f file: perf_sample_start httperf.c /^static Time perf_sample_start;$/;" v file: port conn.h /^ int port; \/* server's port (or -1 for default) *\/$/;" m struct:Conn port core.c /^ int port;$/;" m struct:hash_entry file: port gen/videosesslog.c /^ int port; \/* specifies port used for this session, 0 => use default *\/$/;" m struct:Sess_Private_Data file: port httperf.h /^ int port[MAX_SVR_PORTS];$/;" m struct:Cmdline_Params::__anon10 port httperf.h /^ int port; \/* (default) server port *\/$/;" m struct:Cmdline_Params port sess.h /^ int port; \/* port to use for connections, 0 => use default *\/$/;" m struct:Sess port_free_map core.c /^static u_long port_free_map[((MAX_IP_PORT - MIN_IP_PORT + BITSPERLONG)$/;" v file: port_get core.c /^port_get (void)$/;" f file: port_put core.c /^port_put (int port)$/;" f file: posixly_correct lib/getopt.c /^static char *posixly_correct;$/;" v file: prefix Makefile /^prefix = \/usr\/local$/;" m prefix gen/Makefile /^prefix = \/usr\/local$/;" m prefix gen/wsesspage.c /^static char *prefix;$/;" v file: prefix lib/Makefile /^prefix = \/usr\/local$/;" m prefix stat/Makefile /^prefix = \/usr\/local$/;" m prefix_len gen/wsesspage.c /^static size_t prefix_len;$/;" v file: prepare_for_next_burst gen/videosesslog.c /^prepare_for_next_burst (Sess *sess, Sess_Private_Data *priv, Time conn_time)$/;" f file: prev timer.h /^ struct Timer *prev;$/;" m struct:Timer_Queue typeref:struct:Timer_Queue::Timer prev_f stat/call_stats.c /^struct f_uri_size *prev_f = NULL;$/;" v typeref:struct:f_uri_size print_buf stat/print_reply.c /^print_buf (Call *call, const char *prefix, const char *buf, int len)$/;" f file: print_call stat/call_stats.c /^print_call (call_data cd)$/;" f print_call_stats stat/call_stats.c /^print_call_stats()$/;" f print_connected_info stat/basic.c /^print_connected_info(char *func, int sd, int state)$/;" f print_connected_info stat/basic.c 85;" d file: print_count stat/call_stats.c /^int print_count = 0;$/;" v print_errno_info stat/basic.c /^print_errno_info()$/;" f print_header_line stat/call_stats.c /^print_header_line()$/;" f print_info stat/call_stats.c /^struct print_stats print_info[]={$/;" v typeref:struct:print_stats print_remaining_uri gen/videosesslog.c /^print_remaining_uri (Conn *conn)$/;" f print_reply httperf.h /^ int print_reply; \/* bit 0: print repl headers, bit 1: print repl body *\/$/;" m struct:Cmdline_Params print_reply_hdr stat/print_reply.c /^print_reply_hdr (Call *call, const char *buf, int len)$/;" f file: print_request httperf.h /^ int print_request; \/* bit 0: print req headers, bit 1: print req body *\/$/;" m struct:Cmdline_Params print_request stat/print_reply.c /^print_request (Call *call)$/;" f file: print_spec_timeouts stat/spec_stats.c /^void print_spec_timeouts() {$/;" f print_stats stat/call_stats.c /^struct print_stats {$/;" s file: priv_from_conn gen/videosesslog.c /^priv_from_conn (Conn *conn)$/;" f process_call_timeout stat/call_stats.c /^void process_call_timeout(Conn * c )$/;" f process_spec_timeout stat/spec_stats.c /^void process_spec_timeout(Conn * c ) {$/;" f prog_name httperf.c /^const char *prog_name;$/;" v prog_name idleconn.c /^const char *prog_name;$/;" v prog_name ttest.c /^const char *prog_name = "ttest";$/;" v prv_missed_req gen/videosesslog.c /^ REQ *prv_missed_req;$/;" m struct:Sess_Private_Data file: q timer.h /^ Timer_Queue q; \/* must be first member! *\/$/;" m struct:Timer ramp_down_conns httperf.h /^ int ramp_down_conns; \/* num of conns to ignore at end of experiment *\/$/;" m struct:Cmdline_Params ramp_up_conns httperf.h /^ int ramp_up_conns; \/* num of conns to ignore at beginning of experiment *\/$/;" m struct:Cmdline_Params rate gen/rate.h /^ Rate_Info *rate;$/;" m struct:Rate_Generator rate httperf.h /^ Rate_Info rate;$/;" m struct:Cmdline_Params rate_generator_start gen/rate.c /^rate_generator_start (Rate_Generator *rg, Event_Type completion_event)$/;" f rate_generator_stop gen/rate.c /^rate_generator_stop (Rate_Generator *rg)$/;" f rate_h gen/rate.h 26;" d rate_interval httperf.h /^ double rate_interval; \/* interval at which rate info is sampled *\/$/;" m struct:Cmdline_Params rate_max stat/sess_stat.c /^ Time rate_max;$/;" m struct:__anon15 file: rate_min stat/sess_stat.c /^ Time rate_min;$/;" m struct:__anon15 file: rate_param httperf.h /^ double rate_param; \/* 0 if mean_iat==0, else 1\/mean_iat *\/$/;" m struct:Rate_Info rate_sum stat/sess_stat.c /^ Time rate_sum;$/;" m struct:__anon15 file: rate_sum2 stat/sess_stat.c /^ Time rate_sum2;$/;" m struct:__anon15 file: rd gen/session.c /^ u_int rd; \/* first pending call *\/$/;" m struct:Sess_Private_Data::Conn_Info file: rdfds core.c /^static big_fd_set rdfds, wrfds;$/;" v file: record_conn_time call.h /^ int record_conn_time;$/;" m struct:Call recv_buffer_size httperf.h /^ int recv_buffer_size;$/;" m struct:Cmdline_Params recv_data stat/print_reply.c /^recv_data (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)$/;" f file: recv_done core.c /^recv_done (Call *call)$/;" f file: recv_raw_data stat/print_reply.c /^recv_raw_data (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)$/;" f file: recv_start stat/basic.c /^recv_start (Event_Type et, Object *obj, Any_Type reg_arg, Any_Type call_arg)$/;" f file: recv_stop stat/basic.c /^recv_stop (Event_Type et, Object *obj, Any_Type reg_arg, Any_Type call_arg)$/;" f file: recv_stop stat/print_reply.c /^recv_stop (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)$/;" f file: recvq conn.h /^ struct Call *recvq; \/* calls waiting for a reply *\/$/;" m struct:Conn typeref:struct:Conn::Call recvq_next call.h /^ struct Call *recvq_next;$/;" m struct:Call typeref:struct:Call::Call recvq_tail conn.h /^ struct Call *recvq_tail;$/;" m struct:Conn typeref:struct:Conn::Call ref_count object.h /^ u_int ref_count; \/* # of references to this object *\/$/;" m struct:Object replies stat/spec_stats.c /^ int replies; \/* Number of replies that were received *\/$/;" m struct:__anon17 file: reply call.h /^ reply;$/;" m struct:Call typeref:struct:Call::__anon3 reply_bytes_received stat/basic.c /^ u_wide reply_bytes_received; \/* sum of all data bytes *\/$/;" m struct:__anon13 file: reply_rate_max stat/basic.c /^ Time reply_rate_max;$/;" m struct:__anon13 file: reply_rate_min stat/basic.c /^ Time reply_rate_min;$/;" m struct:__anon13 file: reply_rate_sum stat/basic.c /^ Time reply_rate_sum;$/;" m struct:__anon13 file: reply_rate_sum2 stat/basic.c /^ Time reply_rate_sum2;$/;" m struct:__anon13 file: req call.h /^ req;$/;" m struct:Call typeref:struct:Call::__anon2 req gen/videosesslog.c /^struct req$/;" s file: req_bytes_sent stat/basic.c /^ size_t req_bytes_sent;$/;" m struct:__anon13 file: req_list gen/videosesslog.c /^ REQ *req_list;$/;" m struct:burst file: request_mix_cdf gen/videosesslog.c /^double* request_mix_cdf = NULL;$/;" v requests stat/spec_stats.c /^ int requests; \/* Number of requests sent over sessions of this length *\/$/;" m struct:__anon17 file: requests stat/spec_stats.c /^ int requests; \/* Number of times this file was requested *\/$/;" m struct:__anon16 file: required_argument lib/getopt.h 98;" d retry_on_failure httperf.h /^ int retry_on_failure; \/* when a call fails, should we retry? *\/$/;" m struct:Cmdline_Params rg gen/conn_rate.c /^static Rate_Generator rg;$/;" v file: rg_sess gen/videosesslog.c /^static Rate_Generator rg_sess;$/;" v file: rg_sess gen/wsess.c /^static Rate_Generator rg_sess;$/;" v file: rg_sess gen/wsesspage.c /^static Rate_Generator rg_sess;$/;" v file: running core.c /^static int running = 1;$/;" v file: sched_getaffinity sys_sched_affinity.c /^sched_getaffinity(pid_t pid, unsigned int len, unsigned long *cpu_mask)$/;" f sched_setaffinity sys_sched_affinity.c /^sched_setaffinity(pid_t pid, unsigned int len, unsigned long *cpu_mask)$/;" f schedule_timeouts core.c /^schedule_timeouts (Conn *s)$/;" f file: sd conn.h /^ int sd; \/* socket descriptor *\/$/;" m struct:Conn sd_to_conn core.c /^Conn **sd_to_conn;$/;" v select_time core.c /^ static float timer_tick_time, select_time, work_time;$/;" v file: select_timeout core.c /^static struct timeval select_timeout;$/;" v typeref:struct:timeval file: send_buffer_size httperf.h /^ int send_buffer_size;$/;" m struct:Cmdline_Params send_calls gen/session.c /^send_calls (Sess *sess, struct Conn_Info *ci)$/;" f file: send_raw_data stat/print_reply.c /^send_raw_data (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)$/;" f file: send_start stat/basic.c /^send_start (Event_Type et, Object *obj, Any_Type reg_arg, Any_Type call_arg)$/;" f file: send_stop stat/basic.c /^send_stop (Event_Type et, Object *obj, Any_Type reg_arg, Any_Type call_arg)$/;" f file: sendq conn.h /^ struct Call *sendq; \/* calls whose request needs to be sent *\/$/;" m struct:Conn typeref:struct:Conn::Call sendq_next call.h /^ struct Call *sendq_next;$/;" m struct:Call typeref:struct:Call::Call sendq_tail conn.h /^ struct Call *sendq_tail;$/;" m struct:Conn typeref:struct:Conn::Call separate_post_stats httperf.h /^ int separate_post_stats; \/* Should we separate stats for dyanmic POST requests? *\/$/;" m struct:Cmdline_Params server gen/videosesslog.c /^ const char *server; \/* specifies server used for this session, NULL => use default *\/ $/;" m struct:Sess_Private_Data file: server httperf.h /^ const char *server; \/* (default) hostname *\/$/;" m struct:Cmdline_Params server sess.h /^ const char *server; \/*server to use for connections, NULL => use default *\/$/;" m struct:Sess server_name httperf.h /^ const char *server_name; \/* fully qualified server name *\/$/;" m struct:Cmdline_Params sess gen/session.c /^ Sess *sess;$/;" m struct:Call_Private_Data file: sess gen/session.c /^ Sess *sess;$/;" m struct:Conn_Private_Data file: sess_cookie gen/sess_cookie.c /^Load_Generator sess_cookie =$/;" v sess_create gen/videosesslog.c /^sess_create (Any_Type arg)$/;" f file: sess_create gen/wsess.c /^sess_create (Any_Type arg)$/;" f file: sess_create gen/wsesspage.c /^sess_create (Any_Type arg)$/;" f file: sess_created stat/sess_stat.c /^sess_created (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)$/;" f file: sess_dec_ref sess.h 67;" d sess_deinit sess.c /^sess_deinit (Sess *sess)$/;" f sess_destroyed gen/session.c /^sess_destroyed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)$/;" f file: sess_destroyed gen/videosesslog.c /^sess_destroyed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)$/;" f file: sess_destroyed gen/wsess.c /^sess_destroyed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)$/;" f file: sess_destroyed gen/wsesspage.c /^sess_destroyed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)$/;" f file: sess_destroyed stat/sess_stat.c /^sess_destroyed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)$/;" f file: sess_failure sess.c /^sess_failure (Sess *sess)$/;" f sess_h sess.h 26;" d sess_inc_ref sess.h 66;" d sess_init sess.c /^sess_init (Sess *sess)$/;" f sess_new sess.h 65;" d sess_perc httperf.h /^ double sess_perc[MAX_LOG_FILES]; \/* Array of percentile for request-mix probability *\/$/;" m struct:Cmdline_Params::__anon11 sess_private_data_offset gen/sess_cookie.c /^static size_t sess_private_data_offset = -1;$/;" v file: sess_private_data_offset gen/session.c /^static size_t sess_private_data_offset = -1;$/;" v file: sess_private_data_offset gen/videosesslog.c /^static size_t sess_private_data_offset;$/;" v file: sess_private_data_offset gen/wsess.c /^static size_t sess_private_data_offset;$/;" v file: sess_private_data_offset gen/wsesspage.c /^static size_t sess_private_data_offset;$/;" v file: sess_private_data_offset stat/sess_stat.c /^static size_t sess_private_data_offset = -1;$/;" v file: sess_stats stat/spec_stats.c /^session_data sess_stats[MAX_SESSION];$/;" v session_cookies httperf.h /^ int session_cookies; \/* handle set-cookies? (at the session level) *\/$/;" m struct:Cmdline_Params session_current_qlen gen/session.c /^session_current_qlen (Sess *sess)$/;" f session_data stat/spec_stats.c /^} session_data;$/;" t typeref:struct:__anon17 file: session_get_last_call gen/session.c /^session_get_last_call (Conn *conn)$/;" f session_get_sess_from_call gen/session.c /^session_get_sess_from_call (Call *call)$/;" f session_get_sess_from_conn gen/session.c /^session_get_sess_from_conn (Conn *conn)$/;" f session_h gen/session.h 26;" d session_init gen/session.c /^session_init (void)$/;" f session_issue_call gen/session.c /^session_issue_call (Sess *sess, Call *call)$/;" f session_logs gen/videosesslog.c /^static Session_Log_Desc* session_logs;$/;" v file: session_max_qlen gen/session.c /^session_max_qlen (Sess *sess)$/;" f session_offsets httperf.h /^ int session_offsets; \/* should each client start in a different position$/;" m struct:Cmdline_Params session_stat stat/sess_stat.c /^Stat_Collector session_stat =$/;" v session_templates gen/videosesslog.c /^ Sess_Private_Data session_templates[MAX_SESSION_TEMPLATES]; $/;" m struct:Session_Log_Desc file: set_active core.c /^set_active (Conn *s, big_fd_set *fdset)$/;" f file: set_missed_calls gen/videosesslog.c /^set_missed_calls(Conn *conn)$/;" f set_uri gen/uri_fixed.c /^set_uri (Event_Type et, Call *call)$/;" f file: set_uri gen/uri_wlog.c /^set_uri (Event_Type et, Call * c)$/;" f file: set_uri gen/uri_wset.c /^set_uri (Event_Type et, Call *c)$/;" f file: sigint_handler idleconn.c /^sigint_handler (int signal)$/;" f sin core.c /^ struct sockaddr_in sin;$/;" m struct:hash_entry typeref:struct:hash_entry::sockaddr_in file: size call.h /^ size_t size; \/* # of bytes sent *\/$/;" m struct:Call::__anon2 size stat/print_reply.c /^ size_t size; \/* number of bytes allocated for "line" buffer *\/$/;" m struct:Call_Private_Data file: size stat/spec_stats.c /^ int size; \/* Size of this file (unused for now) *\/ $/;" m struct:__anon16 file: spec_file_data stat/spec_stats.c /^} spec_file_data;$/;" t typeref:struct:__anon16 file: spec_hash stat/spec_stats.c /^int spec_hash( char * uri ) {$/;" f spec_stats httperf.h /^ int spec_stats; \/* Should we gather SPECweb99 specific statistics? *\/$/;" m struct:Cmdline_Params spec_stats_init stat/spec_stats.c /^void spec_stats_init() {$/;" f srcdir Makefile /^srcdir = .$/;" m srcdir gen/Makefile /^srcdir = .$/;" m srcdir stat/Makefile /^srcdir = .$/;" m ssl conn.h /^ SSL *ssl; \/* SSL connection info *\/$/;" m struct:Conn ssl sess.h /^ SSL *ssl; \/* SSL session (or NULL) *\/$/;" m struct:Sess ssl_cipher_list httperf.h /^ const char *ssl_cipher_list; \/* client's list of SSL cipher suites *\/$/;" m struct:Cmdline_Params ssl_ctx httperf.c /^SSL_CTX *ssl_ctx;$/;" v ssl_reuse httperf.h /^ int ssl_reuse; \/* reuse SSL Session ID *\/$/;" m struct:Cmdline_Params st stat/sess_stat.c /^st;$/;" v typeref:struct:__anon15 file: stable_conns_end stat/basic.c /^static long stable_conns_end; \/* ignore connections starting from this id *\/$/;" v file: stable_conns_start stat/basic.c /^static long stable_conns_start; \/* number of connections to ignore at beginning *\/$/;" v file: stable_stats_init stat/basic.c /^stable_stats_init(void)$/;" f file: stagger_start httperf.h /^ int stagger_start;$/;" m struct:Cmdline_Params::__anon9 start gen/conn_rate.c /^start (void)$/;" f file: start gen/rate.h /^ Time start;$/;" m struct:Rate_Generator start gen/videosesslog.c /^start (void)$/;" f file: start gen/wsess.c /^start (void)$/;" f file: start gen/wsesspage.c /^start (void)$/;" f file: start httperf.h /^ void (*start) (void);$/;" m struct:Load_Generator start httperf.h /^ void (*start) (void);$/;" m struct:Stat_Collector start_time idleconn.c /^struct timeval start_time;$/;" v typeref:struct:timeval state conn.h /^ Conn_State state;$/;" m struct:Conn state gen/wsesspage.c /^ state;$/;" m struct:Call_Private_Data typeref:enum:Call_Private_Data::__anon6 file: stats_basic stat/basic.c /^Stat_Collector stats_basic =$/;" v stats_h stat/stats.h 26;" d stats_interval httperf.h /^ int stats_interval; \/* print summary statistics every N seconds *\/$/;" m struct:Cmdline_Params stats_print_reply stat/print_reply.c /^Stat_Collector stats_print_reply =$/;" v status call.h /^ int status;$/;" m struct:Call::__anon3 stop httperf.h /^ void (*stop) (void);$/;" m struct:Load_Generator stop httperf.h /^ void (*stop) (void);$/;" m struct:Stat_Collector stop_wlog gen/uri_wlog.c /^stop_wlog (void)$/;" f file: sum_resp_times stat/spec_stats.c /^ double sum_resp_times; \/* Sum of response times for requests of this file *\/$/;" m struct:__anon16 file: syscall_count core.c /^static u_int syscall_count[SC_NUM_SYSCALLS];$/;" v file: syscall_name core.c /^static const char * const syscall_name[SC_NUM_SYSCALLS] =$/;" v file: syscall_time core.c /^static Time syscall_time[SC_NUM_SYSCALLS];$/;" v file: t1 ttest.c /^Timer *t1, *t2;$/;" v t2 ttest.c /^Timer *t1, *t2;$/;" v t_curr timer.c /^static Timer *t_curr = 0;$/;" v file: test_rusage_start httperf.c /^struct rusage test_rusage_start;$/;" v typeref:struct:rusage test_rusage_stop httperf.c /^struct rusage test_rusage_stop;$/;" v typeref:struct:rusage test_time_start httperf.c /^Time test_time_start;$/;" v test_time_stop httperf.c /^Time test_time_stop;$/;" v think_time httperf.h /^ Time think_time; \/* user think time between calls *\/$/;" m struct:Cmdline_Params::__anon11 think_timeout httperf.h /^ Time think_timeout; \/* timeout for server think time *\/$/;" m struct:Cmdline_Params throughput_max stat/basic.c /^ double throughput_max;$/;" m struct:__anon13 file: throughput_min stat/basic.c /^ double throughput_min;$/;" m struct:__anon13 file: throughput_sum stat/basic.c /^ double throughput_sum;$/;" m struct:__anon13 file: throughput_sum2 stat/basic.c /^ double throughput_sum2;$/;" m struct:__anon13 file: tick gen/rate.c /^tick (Timer *t, Any_Type arg)$/;" f file: tick gen/rate.h /^ int (*tick) (Any_Type arg);$/;" m struct:Rate_Generator time_connect_start conn.h /^ Time time_connect_start; \/* time connect() got called *\/$/;" m struct:Conn::__anon4 time_of_timeout conn.h /^ Time time_of_timeout; \/* time connection timeout occurs (if it occurs) *\/$/;" m struct:Conn::__anon4 time_recv_start call.h /^ Time time_recv_start;$/;" m struct:Call::__anon1 time_send_start call.h /^ Time time_send_start;$/;" m struct:Call::__anon1 time_to_connect conn.h /^ Time time_to_connect; \/* time to connect *\/$/;" m struct:Conn::__anon4 timed_out conn.h /^ int timed_out; \/* did this connection time out?*\/$/;" m struct:Conn timelimit call.h /^ Time timelimit;$/;" m struct:Call timelimit gen/videosesslog.c /^ int timelimit;$/;" m struct:req file: timeout call.h /^ Time timeout; \/* used for watchdog management *\/$/;" m struct:Call timeout httperf.h /^ Time timeout; \/* watchdog timeout *\/$/;" m struct:Cmdline_Params timeout_replies stat/basic.c /^ int timeout_replies; \/* num replies recvd from conns that eventually timed out *\/$/;" m struct:__anon13 file: timeout_with_reset httperf.h /^ int timeout_with_reset; \/* one timeout close connections with TCP RESET? *\/$/;" m struct:Cmdline_Params timeouts stat/spec_stats.c /^ int timeouts; \/* Number of timeouts for sessions of this length *\/$/;" m struct:__anon17 file: timeouts stat/spec_stats.c /^ int timeouts; \/* Number of requests that timed out *\/$/;" m struct:__anon16 file: timer gen/rate.h /^ Timer *timer;$/;" m struct:Rate_Generator timer gen/videosesslog.c /^ Timer *timer; \/* timer for session think time *\/$/;" m struct:Sess_Private_Data file: timer gen/wsess.c /^ Timer *timer; \/* timer for session think time *\/$/;" m struct:Sess_Private_Data file: timer gen/wsesspage.c /^ Timer *timer; \/* timer for session think time *\/$/;" m struct:Sess_Private_Data file: timer_cancel timer.c /^timer_cancel (Timer *t)$/;" f timer_free_list timer.c /^static Timer *timer_free_list = 0;$/;" v file: timer_h timer.h 26;" d timer_init timer.c /^timer_init (void)$/;" f timer_now timer.c /^timer_now (void)$/;" f timer_now_forced timer.c /^timer_now_forced (void)$/;" f timer_schedule timer.c /^timer_schedule (Timer_Callback timeout, Any_Type arg, Time delay)$/;" f timer_tick timer.c /^timer_tick (void)$/;" f timer_tick_time core.c /^ static float timer_tick_time, select_time, work_time;$/;" v file: to_free gen/wsesspage.c /^ void *to_free; \/* call queue element to free when done *\/$/;" m struct:Call_Private_Data file: top_builddir Makefile /^top_builddir = .$/;" m top_builddir gen/Makefile /^top_builddir = ..$/;" m top_builddir lib/Makefile /^top_builddir = ..$/;" m top_builddir stat/Makefile /^top_builddir = ..$/;" m top_srcdir Makefile /^top_srcdir = .$/;" m top_srcdir gen/Makefile /^top_srcdir = ..$/;" m top_srcdir lib/Makefile /^top_srcdir = ..$/;" m top_srcdir stat/Makefile /^top_srcdir = ..$/;" m total_num_reqs gen/videosesslog.c /^ int total_num_reqs; \/* total number of requests in this session *\/$/;" m struct:Sess_Private_Data file: track_call_reply stat/call_stats.c /^void track_call_reply(Call * c, double transfer_time)$/;" f track_call_request stat/call_stats.c /^void track_call_request(Call *c )$/;" f track_call_response stat/call_stats.c /^void track_call_response(Call * c, double response_start_time)$/;" f track_spec_connection stat/spec_stats.c /^void track_spec_connection(Conn * c ) {$/;" f track_spec_reply stat/spec_stats.c /^void track_spec_reply(Call * c, double transfer_time ) {$/;" f track_spec_request stat/spec_stats.c /^void track_spec_request(Call *c ) {$/;" f track_spec_response stat/spec_stats.c /^void track_spec_response(Call * c, double response_start_time ) {$/;" f type event.h /^ Event_Type type;$/;" m struct:Event type object.h /^ Object_Type type;$/;" m struct:Object type_size object.c /^static size_t type_size[OBJ_NUM_TYPES] =$/;" v file: u_wide config.h 120;" d uc httperf.h /^ u_char uc;$/;" m union:__anon8 ui httperf.h /^ u_int ui;$/;" m union:__anon8 ul httperf.h /^ u_long ul;$/;" m union:__anon8 unescape gen/misc.c /^unescape (const char *str, size_t *len)$/;" f file: units stat/call_stats.c /^ char *units; \/* units for data *\/$/;" m struct:print_stats file: update_epoll_event core.c /^update_epoll_event (Conn *s)$/;" f file: uri gen/videosesslog.c /^ char *uri;$/;" m struct:req file: uri gen/wsesspage.c /^ char uri[1]; \/* really URI_LEN+1 bytes... *\/$/;" m struct:Sess_Private_Data::uri_list file: uri httperf.h /^ const char *uri; \/* (default) uri *\/$/;" m struct:Cmdline_Params uri_fixed gen/uri_fixed.c /^Load_Generator uri_fixed =$/;" v uri_len gen/uri_fixed.c /^static size_t uri_len;$/;" v file: uri_len gen/videosesslog.c /^ int uri_len;$/;" m struct:req file: uri_len gen/wsesspage.c /^ size_t uri_len;$/;" m struct:Sess_Private_Data::uri_list file: uri_list gen/wsesspage.c /^ *uri_list;$/;" m struct:Sess_Private_Data typeref:struct:Sess_Private_Data::uri_list file: uri_list gen/wsesspage.c /^ struct uri_list$/;" s struct:Sess_Private_Data file: uri_prefix_len gen/uri_wset.c /^static size_t uri_prefix_len;$/;" v file: uri_wlog gen/uri_wlog.c /^Load_Generator uri_wlog =$/;" v uri_wset gen/uri_wset.c /^Load_Generator uri_wset =$/;" v usage httperf.c /^usage (void)$/;" f file: use_epoll httperf.h /^ int use_epoll; \/* use epoll instead of select *\/$/;" m struct:Cmdline_Params use_ssl gen/videosesslog.c /^ int use_ssl; \/* 1 = use ssl, 2 = don't use ssl, other = default*\/$/;" m struct:Sess_Private_Data file: use_ssl httperf.h /^ int use_ssl; \/* connect via SSL *\/$/;" m struct:Cmdline_Params use_ssl sess.h /^ int use_ssl; \/* use ssl=1,don't use ssl=2,default=other *\/$/;" m struct:Sess user_think_time gen/videosesslog.c /^ Time user_think_time;$/;" m struct:burst file: user_think_time_expired gen/videosesslog.c /^user_think_time_expired (Timer *t, Any_Type arg)$/;" f file: user_think_time_expired gen/wsess.c /^user_think_time_expired (Timer *t, Any_Type arg)$/;" f file: user_think_time_expired gen/wsesspage.c /^user_think_time_expired (Timer *t, Any_Type arg)$/;" f file: val lib/getopt.h /^ int val;$/;" m struct:option verbose httperf.c /^int verbose;$/;" v verify_dir httperf.h /^ const char * verify_dir; \/* Directory containing reference file set (for verification) *\/$/;" m struct:Cmdline_Params verify_reply httperf.h /^ int verify_reply; \/* Should we verify (i.e. check the bytes of) SPECweb99 replies*\/$/;" m struct:Cmdline_Params verify_reply_data http.c /^verify_reply_data (Call * c ) {$/;" f version call.h /^ int version; \/* 0x10000*major + minor *\/$/;" m struct:Call::__anon2 version call.h /^ int version; \/* 0x10000*major + minor *\/$/;" m struct:Call::__anon3 video_quality_index conn.h /^ int video_quality_index; \/* The index of the video quality that it is fetching *\/$/;" m struct:Conn videosesslog gen/videosesslog.c /^Load_Generator videosesslog =$/;" v videosesslog httperf.h /^ videosesslog;$/;" m struct:Cmdline_Params typeref:struct:Cmdline_Params::__anon11 vp httperf.h /^ void *vp;$/;" m union:__anon8 vprintf configure /^vprintf();$/;" f watchdog conn.h /^ Timer *watchdog;$/;" m struct:Conn wheel timer.c /^static Timer_Queue wheel[WHEEL_SIZE], *curr = 0;$/;" v file: work_time core.c /^ static float timer_tick_time, select_time, work_time;$/;" v file: wr gen/session.c /^ u_int wr; \/* where to insert next call *\/$/;" m struct:Sess_Private_Data::Conn_Info file: wrfds core.c /^static big_fd_set rdfds, wrfds;$/;" v file: wsess gen/wsess.c /^Load_Generator wsess =$/;" v wsesspage gen/wsesspage.c /^Load_Generator wsesspage =$/;" v xfer_chunked http.c /^xfer_chunked (Call *c, char **bufp, size_t *buf_lenp)$/;" f file: xsubi gen/rate.h /^ u_short xsubi[3]; \/* used for random number generation *\/$/;" m struct:Rate_Generator ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/timeout ================================================ ./README.UW/README.TIMEOUT: if (s->recvq && (timeout == 0.0 || timeout > s->recvq->timeout)) ./README.UW/README.TIMEOUT: timeout = s->recvq->timeout; ./core.c: && s->recvq && now >= s->recvq->timeout) ./core.c: fprintf(stderr, "Receive queue timeout = %f \n", s->recvq->timeout); ./core.c: if (s->recvq && (timeout == 0.0 || timeout > s->recvq->timeout)) ./core.c: timeout = s->recvq->timeout; Binary file ./.core.c.swp matches ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/timer.c ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #define WHEEL_SIZE 4096 static Time now; static Time next_tick; static Timer *timer_free_list = 0; static Timer *t_curr = 0; /* What a wheel is made of, no? */ static Timer_Queue wheel[WHEEL_SIZE], *curr = 0; static void done (Timer *t) { t->q.next = timer_free_list; t->q.prev = 0; timer_free_list = t; } Time timer_now_forced (void) { struct timeval tv; gettimeofday (&tv, 0); return tv.tv_sec + tv.tv_usec*1e-6; } Time timer_now (void) { return now; } void timer_init (void) { now = timer_now_forced (); memset (wheel, 0, sizeof (wheel)); next_tick = timer_now () + TIMER_INTERVAL; curr = wheel; } void timer_tick (void) { Timer *t, *t_next; int outer_count = 0, inner_count = 0; assert (!t_curr); now = timer_now_forced (); while (timer_now () >= next_tick) { outer_count++; for (t = curr->next; t && t->delta == 0; t = t_next) { inner_count++; t_curr = t; (*t->func) (t, t->arg); t_next = t->q.next; done (t); } t_curr = 0; curr->next = t; if (t) { t->q.prev = (Timer *) curr; --t->delta; } next_tick += TIMER_INTERVAL; if (++curr >= wheel + WHEEL_SIZE) curr = wheel; } /* printf("outer count = %d, inner count = %d\n", outer_count, inner_count); */ } Timer* timer_schedule (Timer_Callback timeout, Any_Type arg, Time delay) { Timer_Queue *spoke; Timer *t, *p; u_long ticks; u_long delta; Time behind; if (timer_free_list) { t = timer_free_list; timer_free_list = t->q.next; } else { t = malloc (sizeof (*t)); if (!t) { fprintf (stderr, "%s.timer_schedule: %s\n", prog_name, strerror (errno)); return 0; } } memset (t, 0, sizeof (*t)); t->func = timeout; t->arg = arg; behind = (timer_now () - next_tick); if (behind > 0.0) delay += behind; if (delay < 0.0) ticks = 1; else { ticks = (delay + TIMER_INTERVAL / 2.0) * (1.0 / TIMER_INTERVAL); if (!ticks) ticks = 1; /* minimum delay is a tick */ } spoke = curr + (ticks % WHEEL_SIZE); if (spoke >= wheel + WHEEL_SIZE) spoke -= WHEEL_SIZE; delta = ticks / WHEEL_SIZE; p = (Timer *) spoke; while (p->q.next && delta > p->q.next->delta) { delta -= p->q.next->delta; p = p->q.next; } t->q.next = p->q.next; t->q.prev = p; p->q.next = t; t->delta = delta; if (t->q.next) { t->q.next->q.prev = t; t->q.next->delta -= delta; } #if 0 if (DBG > 2) fprintf (stderr, "timer_schedule: t=%p, delay=%gs, arg=%lx\n", t, delay, arg.l); #endif return t; } void timer_cancel (Timer *t) { #if 0 if (DBG > 2) fprintf (stderr, "timer_cancel: t=%p\n", t); #endif assert (t->q.prev); /* A module MUST NOT call timer_cancel() for a timer that is currently being processed (whose timeout has expired). */ if (t_curr == t) { fprintf (stderr, "timer_cancel() called on currently active timer!\n"); return; } if (t->q.next) { t->q.next->delta += t->delta; t->q.next->q.prev = t->q.prev; } t->q.prev->q.next = t->q.next; done (t); } ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/timer.h ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef timer_h #define timer_h #include #include #define TIMER_INTERVAL (1.0/1000) /* timer granularity in seconds */ struct Timer; typedef void (*Timer_Callback) (struct Timer *t, Any_Type arg); typedef struct Timer_Queue { struct Timer *next; struct Timer *prev; } Timer_Queue; typedef struct Timer { Timer_Queue q; /* must be first member! */ u_long delta; Timer_Callback func; Any_Type arg; } Timer; extern Time timer_now_forced (void); extern Time timer_now (void); extern void timer_init (void); /* Needs to be called at least once every TIMER_INTERVAL: */ extern void timer_tick (void); extern Timer *timer_schedule (Timer_Callback timeout, Any_Type arg, Time delay); extern void timer_cancel (Timer *t); #endif /* timer_h */ ================================================ FILE: benchmarks/media-streaming/client/files/videoperf/ttest.c ================================================ /* httperf -- a tool for measuring web server performance Copyright (C) 2000 Hewlett-Packard Company Contributed by David Mosberger-Tang This file is part of httperf, a web server performance measurment tool. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include const char *prog_name = "ttest"; Timer *t1, *t2; void expire (struct Timer *t) { Time now = timer_now(); printf ("Timer %p expired at %f\n", t, now); #if 0 if (t == t1) timer_cancel (t2); #endif } int main (int argc, char **argv) { Any_Type a; timer_init (); timer_schedule (expire, ++a.i, 0.0); timer_schedule (expire, ++a.i, 2.0); timer_schedule (expire, ++a.i, 2.0); timer_schedule (expire, ++a.i, 3.0); t1 = timer_schedule (expire, ++a.i, 3.0); t2 = timer_schedule (expire, ++a.i, 5 +3.0); timer_schedule (expire, ++a.i, 3.0); timer_schedule (expire, ++a.i, 10+3.0); timer_schedule (exit, ++a.i, 12+3.0); while (1) { printf("Time: %f\n", timer_now()); timer_tick (); usleep (10000); } } ================================================ FILE: benchmarks/media-streaming/dataset/Dockerfile ================================================ FROM cloudsuite/base-os:ubuntu ENV DEBIAN_FRONTEND noninteractive RUN apt-get update && apt-get install make wget build-essential cmake -y RUN wget https://downloads.xiph.org/releases/ogg/libogg-1.3.4.tar.gz \ && tar -zxvf libogg-1.3.4.tar.gz \ && cd libogg-1.3.4 \ && ./configure \ && make \ && make install \ && cp /usr/local/lib/libogg.so.0.8.4 /usr/lib/$(uname -m)-linux-gnu/libogg.so.0.8.4 \ && ln -s /usr/lib/$(uname -m)-linux-gnu/libogg.so.0.8.4 /usr/lib/$(uname -m)-linux-gnu/libogg.so.0 \ && mkdir build \ && cd build \ && cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=ON -DCPACK_PACKAGE_CONTACT="Xiph.Org Foundation" -DCPACK_PACKAGE_NAME=libogg0 .. \ && cmake --build . \ && cpack -G DEB \ && dpkg -i /libogg-1.3.4/build/libogg0-1.3.4-Linux.deb RUN apt-get update && apt-get upgrade -y && apt-get autoremove -y \ && apt-get install -y --no-install-recommends \ libavcodec58 libavfilter7 \ libavdevice58 libavformat58 \ libchromaprint1 libflac8 \ libvorbisenc2 \ software-properties-common \ build-essential \ curl \ wget \ yasm \ ffmpeg \ && rm -rf /var/lib/apt/lists/* COPY files /root/ RUN chmod 755 /root/download_video_files.sh RUN /root/download_video_files.sh ADD bootstrap.sh /root/bootstrap.sh RUN chown root:root /root/bootstrap.sh RUN chmod 700 /root/bootstrap.sh VOLUME ["/videos"] ENTRYPOINT ["/root/bootstrap.sh"] ================================================ FILE: benchmarks/media-streaming/dataset/bootstrap.sh ================================================ #!/bin/bash DIR="/videos" LIBRARY_SIZE=$1 SESSIONS_SIZE=$2 if [[ ( ! -z $FORCE && $FORCE == "true" ) ]]; then rm -rf /videos/ fi if [ "$(ls -A $DIR)" ]; then echo "Dataset Exists! set environment variable FORCE='true' to recreate the Dataset (-e FORCE=true)" else cd /root/filegen && make && ./generate_video_files_and_logs.sh /videos /root/VideoSet $LIBRARY_SIZE $SESSIONS_SIZE rm -rf /root/VideoSet rm -rf /root/filegen fi ================================================ FILE: benchmarks/media-streaming/dataset/files/download_video_files.sh ================================================ #!/bin/sh mkdir -p /root/VideoSet cd /root/VideoSet mkdir -p 240p; cd 240p for i in `seq 1 9` do curl -O https://cloudsuite.ch/download/media_streaming/VideoSet/240p/240_${i}.mp4 done cd .. mkdir -p 360p; cd 360p for i in `seq 1 9` do curl -O https://cloudsuite.ch/download/media_streaming/VideoSet/360p/360_${i}.mp4 done cd .. mkdir -p 480p; cd 480p for i in `seq 1 9` do curl -O https://cloudsuite.ch/download/media_streaming/VideoSet/480p/480_${i}.mp4 done cd .. mkdir -p 720p; cd 720p for i in `seq 1 9` do curl -O https://cloudsuite.ch/download/media_streaming/VideoSet/720p/720_${i}.mp4 done cd .. ================================================ FILE: benchmarks/media-streaming/dataset/files/filegen/Makefile ================================================ CC = gcc CFLAGS = -Wall -g LIBS = -lm all: make_zipf gen_fileset .PHONY: all make_zipf: make_zipf.c $(CC) $(CFLAGS) -o $@ $^ $(LIBS) gen_fileset: gen_fileset.c $(CC) $(CFLAGS) -o $@ $^ $(LIBS) ================================================ FILE: benchmarks/media-streaming/dataset/files/filegen/gen_fileset.c ================================================ /* gen_fileset Creates a full set of video files using the contents of video_files.txt This file is Copyright (C) 2011 Jim Summers Authors: Jim Summers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include static char *basename; static char *fileset_list_filename; /* files will be rounded up to a multiple of round_size */ static int round_size = 1; static int create_file( char *fname, int size ); int main(int argc, char *argv[]) { FILE *f; char file_line[100]; char filename[100]; char *curr; int file_num; int file_bytes; double file_time; int count; /* get basename for files and the list of files to create */ if (argc < 3 || argc > 4) { printf( "Usage: %s {round_size}\n", argv[0] ); exit( 1 ); } basename = argv[1]; fileset_list_filename = argv[2]; if (argc > 3) { round_size = strtol( argv[3], NULL, 10 ); printf( "Creating full files rounded to size %d specified in file %s.\n", round_size, fileset_list_filename ); } else { printf( "Creating full files specified in file %s.\n", fileset_list_filename ); } /* open file list and skip to first useful line */ f = fopen( fileset_list_filename, "rt" ); while ((curr = fgets( file_line, sizeof( file_line ), f )) != NULL) { if (file_line[0] != '#') break; } count = 0; while (curr != NULL) { if (sscanf( curr, "%d %d %lf", &file_num, &file_bytes, &file_time ) != 3) { printf( "Error in format: %s\n", curr ); exit( 1 ); } sprintf( filename, "%s%05d.txt", basename, file_num ); if (count++ % 50 == 0) { printf( "%s %d %.3f seconds\n", filename, file_bytes, file_time ); } if (create_file( filename, file_bytes ) != 0) { fprintf(stderr, "Error creating file. Exiting ...\n"); exit(1); } curr = fgets( file_line, sizeof( file_line ), f ); } exit( 0 ); } /* * create file with specified name and size */ static int create_file( char *fname, int size ) { FILE *fout; #define BLOCK_SIZE 64 char filler[BLOCK_SIZE+1]; int num_blocks; int end; int i,j; /* round size up to chunk size */ if (round_size > 1) { size = ((size + round_size - 1) / round_size) * round_size; } num_blocks = size / BLOCK_SIZE; if ((fout = fopen( fname, "w+" )) == NULL) { return( errno ); } for (i=0;i 0 && filler[j] != ' ') { --j; } /* repeat line number until buffer is full */ do { filler[end++] = filler[j++]; } while (end < BLOCK_SIZE-1); filler[BLOCK_SIZE-1] = '\n'; filler[BLOCK_SIZE] = '\0'; } fputs( filler, fout ); } /* add last partial block */ i = size - num_blocks * BLOCK_SIZE; if (i > 0) { fprintf( fout, "%.*s\n", i-1, filler ); } fclose( fout ); return( 0 ); } ================================================ FILE: benchmarks/media-streaming/dataset/files/filegen/generate_video_files_and_logs.sh ================================================ #!/bin/bash VIDEOS_DIR=$1 VIDEO_SET=$2 LIBRARY_SIZE=$3 SESSIONS_SIZE=$4 mkdir -p "$VIDEOS_DIR/logs" touch "$VIDEOS_DIR/test_videos.js" chmod 744 "$VIDEOS_DIR/test_videos.js" for paramfile in params/*; do mkdir /tmp/textpaths cp "$paramfile" filegen_param.conf if [ ! -z "$LIBRARY_SIZE" ]; then filename=filegen_param.conf test_pattern=library_size while IFS='' read -r line || [[ -n "$line" ]]; do if [[ $line =~ $test_pattern ]]; then param_to_search_and_replace=$line fi done < "$filename" old_size="$(cut -d'=' -f2 <<<"$param_to_search_and_replace")" if [ "$LIBRARY_SIZE" -lt 52 ] then multiplication_factor=`expr 520 \* $LIBRARY_SIZE` else multiplication_factor=`expr 500 \* $LIBRARY_SIZE` fi new_size=$[$multiplication_factor / 151] new_size=$[$new_size + 1] sed -i "s/$test_pattern=$old_size/$test_pattern=$new_size/g" $filename fi if [ ! -z "$SESSIONS_SIZE" ]; then filename=filegen_param.conf test_pattern=num_log_sessions while IFS='' read -r line || [[ -n "$line" ]]; do if [[ $line =~ $test_pattern ]]; then param_to_search_and_replace=$line fi done < "$filename" old_size="$(cut -d'=' -f2 <<<"$param_to_search_and_replace")" new_size=${SESSIONS_SIZE} sed -i "s/$test_pattern=$old_size/$test_pattern=$new_size/g" $filename fi ./make_zipf python3 ./video_gen.py -p filegen_param.conf -v video_files.txt -s "$VIDEO_SET" -o "$VIDEOS_DIR/" cp cl* "$VIDEOS_DIR/logs" rm -rf /tmp/textpaths/* rmdir /tmp/textpaths done ================================================ FILE: benchmarks/media-streaming/dataset/files/filegen/make_zipf.c ================================================ /* make_zipf Creates a set of log files with zipf distribution. This file is Copyright (C) 2011 Jim Summers Authors: Jim Summers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include /* #include #include #include */ #define BYTES_PER_MB (1024*1024) /* output variable-sized chunks */ //#define VBR_CHUNKS /* adjust chunk size by plus or minus this fraction */ #define VBR_FACTOR (0.1) /* For reading the config file */ #define CONFIG_FILENAME "filegen_param.conf" #define CONFIG_MAXBUF 1024 #define CONFIG_DELIM "=" /* user-supplied parameters */ static unsigned long random_seed = 40; static int library_size = 100; /* number of videos available to be chosen. */ static double zipf_exponent = -0.8; /* exponent used to generate Zipf distribution */ static double timeout_per_request = 10; /* maximum time allowed to transmit a request to a client */ static int num_buffering_requests = 3; /* Number of client chunks to request at full speed before */ /* pacing the rest of the requests in the session. */ static int session_time_chunking = 1; /* If greater than 1, session times will be rounded up */ /* to the next multiple higher than this. */ static int video_time_chunking = 1; /* If greater than 1, video times will be rounded to */ /* the nearest multiple of this number. */ static int min_timeout = 10; /* The minimum timeout to use for a session */ static int num_log_files = 3; /* number of client logs to create */ static int num_log_sessions = 20; /* number of sessions per log file */ static int num_sessions; /* total number of video sessions = num_log_files * num_log_sessions */ static int num_client_chunks_requested; /* total number of client chunk requests */ static double max_duration = 800; /* video library durations are truncated to this value when read */ static double max_session; /* duration of the longest session that was used, in seconds */ /* start requests from an offset other than 0. If FIXED, add a */ /* fixed amount. If MIDPOINT, make request out of the middle of */ /* the file. If ENDPOINY, make requests out of the last data in file */ //#define FIXED_OFFSET #define FIXED_OFFSET_BYTES 1000000 //#define MIDPOINT_OFFSET //#define ENDPOINT_OFFSET /* actual values from generated workload */ static double average_video_MB; /* Calculated average size of videos in MB */ /* header lines added to the top of each log file */ #define MAX_HEADER_LINES 50 #define HEADER_LINE_LENGTH 120 static char header_line[MAX_HEADER_LINES][HEADER_LINE_LENGTH]; static int num_header_lines; static char log_basename[] = "cl"; static char preload_basename[] = "fs"; /* information used to create names in the logfiles */ typedef struct { char *log_warm_basename; /* basename for files requested more than once */ char *log_cold_basename; /* basename for files requested only once. */ int num_warm_files; /* number of files to warm cache with */ int fname_num_digits; /* number of digits in number portion of filename */ double client_MB_per_request; /* size of requests by clients */ double file_seconds_per_request; /* number of seconds of video contained in each request */ } logfile_info_struct; /* filenames to used for different libraries */ logfile_info_struct logfile_info[] = { { "full-2040p", "full-2040p", 10000, 5, 50, 10 }, { "full-1440p", "full-1440p", 10000, 5, 12.5, 10 }, { "full-1080p", "full-1080p", 10000, 5, 10, 10 }, { "full-720p", "full-720p", 10000, 5, 6.25, 10 }, { "full-480p", "full-480p", 10000, 5, 3.125, 10 }, { "full-360p", "full-360p", 10000, 5, 1.25, 10 }, { "full-240p", "full-240p", 10000, 5, 0.5, 10 }, { "full-144p", "full-144p", 10000, 5, 0.1, 10 }, }; #define Q2040P 0 #define Q1440P 1 #define Q1080P 2 #define Q720P 3 #define Q480P 4 #define Q360P 5 #define Q240P 6 #define Q144P 7 int video_quality = Q480P; char video_quality_str[10] = "480p"; /* information about each file in a fileset */ struct fs_info_struct; typedef struct { int file_number; /* number of file, for convenience */ struct fs_info_struct *fsi; /* the fileset that contains the video */ double video_dur; /* duration of video in seconds */ int size; /* size of video file in bytes */ int rank; /* rank of video within fileset */ } file_info_struct; /* set of files with the same bitrate and common names */ /* provides mappings between rank and file number */ typedef struct fs_info_struct { int num_files; /* number of files in fileset */ file_info_struct *fi; /* array of information about each file in fileset */ int *video_rank; /* ranks of videos, in index order */ int *video_index; /* index of videos, in rank order */ logfile_info_struct *li; /* information used to create log file entries */ double file_MB_rate; /* data rate of video files, in MB/s */ double *pdf; /* popularity distribution function for the fileset */ } fileset_info_struct; /* information about sessions making up the workload */ /* note that files may be from more than one fileset */ typedef struct { int rank; /* rank of video chosen for session */ fileset_info_struct *fsi; /* the fileset that contains the video */ double duration; /* duration of session */ int client_id; /* which client is responsible for this session */ file_info_struct *fi; /* information about file containing video */ } session_info_struct; static int num_videos; /* number of videos in all the file sets. */ /* array of filesets used for sessions */ static int num_filesets; static fileset_info_struct **fileset_list; /***************************** forward declarations *****************************/ static void create_random_ranks( fileset_info_struct *fsi ); static int create_log_files( session_info_struct *session_info, int total_num_videos ); static void write_file_duration_CDF( void ); /********************************************************************************/ /* PDF of video duration, or time to read entire video. */ /* This is the combination of 4 normal curves with the following parameters: */ #define VIDEO_DUR_SIZE 25 static double video_duration_cdf[VIDEO_DUR_SIZE] = { 0.018, 0.057, 0.109, 0.160, 0.202, 0.247, 0.296, 0.346, 0.395, 0.439, 0.494, 0.544, 0.597, 0.642, 0.692, 0.723, 0.791, 0.817, 0.874, 0.928, 0.960, 0.968, 0.973, 0.990, 1.0 }; static double video_duration[VIDEO_DUR_SIZE] = { 15, 30, 50, 70, 90, 112, 138, 161, 183, 200, 215, 228, 244, 257, 285, 300, 362, 400, 500, 600, 700, 800, 900, 1000, 1000 }; /* * Read the config file, if present. */ void read_config() { FILE *f = fopen(CONFIG_FILENAME, "r"); if (f != NULL) { char line[CONFIG_MAXBUF]; int i = 0; while(fgets(line, sizeof(line), f) != NULL) { char* cfline; cfline = strstr((char*)line, CONFIG_DELIM); cfline = cfline + strlen(CONFIG_DELIM); if (i==0) { library_size = atoi(cfline); } else if (i==1) { num_log_files = atoi(cfline); } else if (i==2) { num_log_sessions = atoi(cfline); } else if (i==3) { printf("quality = %s %d\n", cfline, strcmp(cfline, "240p")); if(strncmp(cfline, "1080p", 5) == 0) { video_quality=2; strcpy(video_quality_str, "1080p"); } else if(strncmp(cfline, "720p", 4) == 0) { video_quality=3; strcpy(video_quality_str, "720p"); } else if(strncmp(cfline, "480p", 4) == 0) { video_quality=4; strcpy(video_quality_str, "480p"); } else if(strncmp(cfline, "360p", 4) == 0) { video_quality=5; strcpy(video_quality_str, "360p"); } else if(strncmp(cfline, "240p", 4) == 0) { video_quality=6; strcpy(video_quality_str, "240p"); } } i++; } fclose(f); } } /* * Find the first cdf value higher than r. Interpolate r between the two straddling * points to determine the chosen value. */ static double interpolate_cdf( double r, /* random number between 0 and 1 */ double *cdf, double *cdf_data, /* data values for each CDF point */ int cdf_size ) { int i; /* search through CDF, don't bother looking at the last value */ cdf_size--; for (i=0; i < cdf_size; ++i) { if (r <= cdf[i]) { break; } } /* interpolate results */ if (i == 0) { return( r / cdf[0] * cdf_data[0] ); } else { return( cdf_data[i] - (cdf_data[i] - cdf_data[i-1]) * (cdf[i] - r) / (cdf[i] - cdf[i-1]) ); } } #define MINIMUM_DURATION 5 #define VIDEO_DUR_HISTOGRAM_SIZE 1000 #define VIDEO_DUR_HISTOGRAM_BINSIZE 1 static int video_duration_histogram[VIDEO_DUR_HISTOGRAM_SIZE]; static int video_duration_histogram_points = 0; /* * Return the duration of a video in seconds. * r is a random number between 0 and 1. */ static double compute_duration( double r ) { int i; double duration; duration = interpolate_cdf( r, video_duration_cdf, video_duration, VIDEO_DUR_SIZE ); if (duration < MINIMUM_DURATION) duration = MINIMUM_DURATION; /* update duration histogram */ i = duration / VIDEO_DUR_HISTOGRAM_BINSIZE; if (i >= VIDEO_DUR_HISTOGRAM_SIZE) i = VIDEO_DUR_HISTOGRAM_SIZE; video_duration_histogram[i]++; video_duration_histogram_points++; return( duration ); } /* CDF of session lengths. This is the fraction of a full file that will be read. */ #define SESSION_FRAC_SIZE 20 static double session_frac_cdf[SESSION_FRAC_SIZE] = { 0.050, 0.100, 0.150, 0.200, 0.250, 0.300, 0.350, 0.400, 0.450, 0.500, 0.550, 0.600, 0.650, 0.700, 0.750, 0.800, 0.820, 1.000 }; static double session_frac[SESSION_FRAC_SIZE] = { 0.067, 0.122, 0.174, 0.222, 0.277, 0.352, 0.439, 0.537, 0.627, 0.673, 0.708, 0.738, 0.783, 0.835, 0.905, 0.982, 1.000, 1.000 }; #define SESSION_FRAC_HISTOGRAM_SIZE 1000 #define SESSION_FRAC_HISTOGRAM_BINSIZE 0.001 static int session_frac_histogram[SESSION_FRAC_HISTOGRAM_SIZE]; static int session_frac_histogram_points; /* * Return the fraction of a full file to view. * r is a random number between 0 and 1. */ static double compute_session_frac( double r ) { int i; double frac; frac = interpolate_cdf( r, session_frac_cdf, session_frac, SESSION_FRAC_SIZE ); /* update duration histogram */ i = frac / SESSION_FRAC_HISTOGRAM_BINSIZE; if (i >= SESSION_FRAC_HISTOGRAM_SIZE) i = SESSION_FRAC_HISTOGRAM_SIZE; session_frac_histogram[i]++; session_frac_histogram_points++; return( frac ); } /* * Fill the sample array with a Zipf probability distribution. */ static void make_zipf_distribution( double *sample, int num_ranks ) { double rank_total; int rank; /* create zipf distribution */ rank_total=0.0; for (rank=0; rank < num_ranks; ++rank) { sample[rank] = pow( rank + 1.0, zipf_exponent ); rank_total += sample[rank]; } /* normalize distribution to compute probabilities */ for (rank=0; rank < num_ranks; ++rank) { sample[rank] /= rank_total; } } /* Helper function for the qsort() routine. We want to sort the ranks in * descending order, so return a negative number when the first item is * larger than the second. */ typedef struct { int num_views; /* number of views */ int index; /* index in original order */ } rank_struct; static int compare_rank_views( const void *c1, const void *c2 ) { return( ((rank_struct *) c2)->num_views - ((rank_struct *) c1)->num_views ); } /* * Create a set of file durations to use for the video library */ static fileset_info_struct *create_video_library( int lib_size ) { fileset_info_struct *fsi; double total_duration; int i, j, k; FILE *f; int bin; int num_dur_histogram; int video_dur_hist_size; typedef struct { int *histogram; int size; } histogram_sample_struct; histogram_sample_struct *dur_histogram_sample; histogram_sample_struct *total_dur_histogram; int dur_histogram_sample_size; double video_dur_histogram_bin_size; int *dur_cdf; /* construct duration histograms for subsets of the distribution */ num_dur_histogram = 3; video_dur_hist_size = 100; /* allocate a histogram for each subset and use the last for the total of all histograms */ if ((dur_histogram_sample = calloc( num_dur_histogram+1, sizeof( histogram_sample_struct ) )) == NULL) { printf( "Unable to allocate file duration histogram pointer array.\n" ); exit( 1 ); } for (i=0;ifi = malloc( lib_size * sizeof( file_info_struct ) )) == NULL) { printf( "Unable to allocate file information array.\n" ); exit( 1 ); } fsi->num_files = lib_size; fsi->li = &(logfile_info[ video_quality ]); fsi->file_MB_rate = fsi->li->client_MB_per_request / fsi->li->file_seconds_per_request; total_duration = 0.0; j = dur_histogram_sample_size; k = 0; for (i=0; i < lib_size; ++i) { fsi->fi[i].file_number = i; fsi->fi[i].video_dur = compute_duration( random() / (1.0 + INT_MAX) ); fsi->fi[i].size = fsi->fi[i].video_dur * fsi->file_MB_rate * BYTES_PER_MB; total_duration += fsi->fi[i].video_dur; fsi->fi[i].fsi = fsi; bin = fsi->fi[i].video_dur / video_dur_histogram_bin_size; if (bin >= video_dur_hist_size) { bin = video_dur_hist_size - 1; } dur_histogram_sample[k].histogram[bin]++; dur_histogram_sample[k].size++; total_dur_histogram->histogram[bin]++; total_dur_histogram->size++; /* if a portion is complete, start collecting histogram stats in the next sample */ if (i >= j) { k++; if (k >= num_dur_histogram) k = num_dur_histogram - 1; j += dur_histogram_sample_size; } } assert( total_dur_histogram->size == lib_size ); average_video_MB = total_duration / lib_size * fsi->file_MB_rate; /* write out the file duration CDF */ write_file_duration_CDF(); /* write out the file duration probability distribution */ if ((f = fopen( "video_dur_prob.txt", "w" )) == NULL) { printf( "Error opening file %d\n", errno ); exit( 1 ); } /* output descriptions for columns, assuming 3 duration histograms */ assert( num_dur_histogram == 3 ); fprintf( f, "# video_duration PDF_low PDF_mid PDF_high PDF_all\n" ); if ((dur_cdf = calloc( num_dur_histogram, sizeof( int ) )) == NULL) { printf( "Unable to allocate file duration histogram CDF array.\n" ); exit( 1 ); } j = 0; for (i=0;ihistogram[i] / lib_size ); */ fprintf( f, "%.3f", (i + 0.5) * video_dur_histogram_bin_size ); for (k=0;k<=num_dur_histogram;++k) { fprintf( f, " %.3f", (double) dur_histogram_sample[k].histogram[i] / dur_histogram_sample[k].size ); } fputs( "\n", f ); } fclose( f ); /* create array of ranks for the videos */ if ((fsi->video_rank = malloc( lib_size * sizeof( int ) )) == NULL) { printf( "Unable to allocate video rank array.\n" ); exit( 1 ); } create_random_ranks( fsi ); return( fsi ); } /* * Write out the video_dur_histogram file */ static void write_file_duration_CDF( void ) { FILE *f; int total; int i; if ((f = fopen( "video_dur_histogram.txt", "w" )) == NULL) { printf( "Error opening file %d\n", errno ); exit( 1 ); } fprintf( f, "# video_duration CDF\n" ); total = 0; for (i=0;inum_files != 0 ); assert( fsi->fi != NULL ); assert( fsi->video_rank != NULL ); /* use a random permutation to assign a rank to each video index */ for (i=0;i < fsi->num_files;++i) { j = random() / (1.0 + INT_MAX) * (i+1); fsi->video_rank[i] = fsi->video_rank[j]; fsi->video_rank[j] = i; } /* adjust random permutation so that rank 0 and rank 1 files are */ /* close to the median duration. */ median_size = compute_duration( 0.5 ); for (j=0;j<2;++j) { median_diff = fabs( fsi->fi[0].video_dur - median_size ); median_pos = 0; j_pos = 0; /* find duration closest to the median */ for (i=1;inum_files;++i) { diff = fabs( fsi->fi[i].video_dur - median_size ); if (diff < median_diff) { /* check if this median has already been used */ if (fsi->video_rank[i] > j) { median_diff = diff; median_pos = i; } } /* also find the video with rank j */ if (fsi->video_rank[i] == j) { j_pos = i; } } fsi->video_rank[j_pos] = fsi->video_rank[median_pos]; fsi->video_rank[median_pos] = j; } /* set ranks in file_info structures */ for (i=0;i < fsi->num_files;++i) { fsi->fi[i].rank = fsi->video_rank[i]; } } /* * Read a set of file durations and ranks to use for the video library. * The input file is expected to have the same format as the video_files.txt */ static fileset_info_struct *read_video_library( const char *filename, logfile_info_struct *log_info, int *video_count ) { fileset_info_struct *fsi; FILE *f; int i; int bin; char file_line[300]; int lib_size; int num_files; double total_duration; int file_num; double dur_seconds; int dur_chunks; double sess_dur; int sess_chunks; static char old_header[] = "# num length(B) length(s) length(chunks) max_session(s) max_session(chunks) rank sum_sessions(s)"; int header_version; /* open file, determine which version, and count the number of lines */ f = fopen( filename, "r" ); if (f == NULL) { printf( "Error %d opening video library file \"%s\"\n", errno, filename ); exit( 1 ); } lib_size = 0; header_version = 1; while ((fgets( file_line, sizeof( file_line ), f )) != NULL) { if (file_line[0] == '#') { /* determine if a new or old style video list */ if (strncmp( file_line, old_header, sizeof( old_header ) - 1 ) == 0) { header_version = 0; } continue; } lib_size++; } num_files = lib_size; if (video_count != NULL) *video_count = num_files; if ((fsi = malloc( sizeof( fileset_info_struct ) )) == NULL) { printf( "Unable to allocate library information array.\n" ); exit( 1 ); } fsi->num_files = num_files; fsi->li = log_info; fsi->file_MB_rate = log_info->client_MB_per_request / log_info->file_seconds_per_request; /* create array of file information from library */ if ((fsi->fi = malloc( num_files * sizeof( file_info_struct ) )) == NULL) { printf( "Unable to allocate file information array.\n" ); exit( 1 ); } /* create array ranks */ if ((fsi->video_rank = malloc( num_files * sizeof( int ) )) == NULL) { printf( "Unable to allocate video rank array.\n" ); exit( 1 ); } /* populate video_dur, video_bytes and video_rank arrays from the file */ rewind( f ); total_duration = 0.0; i=0; while (i < lib_size) { if (fgets( file_line, sizeof( file_line ), f ) == NULL) { printf( "Error %d reading video library file \"%s\"\n", errno, filename ); exit( 1 ); } if (file_line[0] == '#') continue; if (header_version == 0) { if (sscanf( file_line, "%d %d %lf %d %lf %d %d", &file_num, &(fsi->fi[i].size), &dur_seconds, &dur_chunks, &sess_dur, &sess_chunks, &(fsi->video_rank[i]) ) != 7) { printf( "Error in video file format: %s\n", file_line ); exit( 1 ); } } else { if (sscanf( file_line, "%d %d %lf %lf %d", &file_num, &(fsi->fi[i].size), &dur_seconds, &sess_dur, &(fsi->video_rank[i]) ) != 5) { printf( "Error in video file format: %s\n", file_line ); exit( 1 ); } } fsi->fi[i].file_number = i; fsi->fi[i].video_dur = (double) fsi->fi[i].size / (fsi->file_MB_rate * BYTES_PER_MB); if (fsi->fi[i].video_dur > max_duration) fsi->fi[i].video_dur = max_duration; fsi->fi[i].fsi = fsi; /* update duration histogram */ bin = fsi->fi[i].video_dur / VIDEO_DUR_HISTOGRAM_BINSIZE; if (bin >= VIDEO_DUR_HISTOGRAM_SIZE) bin = VIDEO_DUR_HISTOGRAM_SIZE; video_duration_histogram[bin]++; video_duration_histogram_points++; /* call random() so that random values used later will be the same as when we originally generated these videos */ random(); total_duration += fsi->fi[i].video_dur; ++i; } fclose( f ); /* write out the file duration CDF */ write_file_duration_CDF(); average_video_MB = total_duration / num_files * fsi->file_MB_rate; return( fsi ); } #ifdef NOT_USED /* * clean up library information */ static void free_video_library( fileset_info_struct *fsi ) { if (fsi != NULL) { fsi->num_files = 0; free( fsi->fi ); free( fsi->video_rank ); free( fsi->video_index ); free( fsi ); } } #endif /* * Create the video_index array, after the video_rank array is initialized. */ static void make_video_index( fileset_info_struct *fsi ) { int i; /* create the inverse mapping, video indices in rank order */ if ((fsi->video_index = malloc( fsi->num_files * sizeof( int ) )) == NULL) { printf( "Unable to allocate video index array.\n" ); exit( 1 ); } for (i=0;i < fsi->num_files;++i) { fsi->video_index[ fsi->video_rank[i] ] = i; } } int main(int argc, char *argv[]) { int rank; int i, j; double duration; double *max_session_time; double *sum_session_time; double total_session_time; double total_unique_session_time; double total_duration; int num_ranks; int total_num_multi; int total; FILE *f; fileset_info_struct *fileset_info; session_info_struct *session_info; logfile_info_struct *log_info; read_config(); /* create text file that can be used for gnuplot titles */ if ((f = fopen( "make_zipf_description.txt", "w" )) == NULL) { printf( "Error opening file %d\n", errno ); exit( 1 ); } num_sessions = num_log_files * num_log_sessions; fprintf( f, "%d videos, %d sessions, Zipf alpha %.3lf\n", library_size, num_sessions, zipf_exponent ); fclose( f ); srandom( random_seed ); /* determine number of filesets supplied on the command line */ num_filesets = argc - 1; if (num_filesets < 1) num_filesets = 1; if ((fileset_list = malloc( num_filesets * sizeof( fileset_info_struct * ) )) == NULL) { printf( "Unable to allocate fileset list.\n" ); exit( 1 ); } /* create or read multiple filesets of videos */ if (argc <= 1) { if ((fileset_list[0] = create_video_library( library_size )) == NULL) { printf( "Error creating video library.\n" ); exit( 1 ); } make_video_index( fileset_list[0] ); num_videos = library_size; fileset_list[0]->li = &(logfile_info[ video_quality ]); } else { for (i=0;inum_files; } /* initialize other per-fileset information */ for (i=0;ipdf = malloc( fileset_list[i]->num_files * sizeof( double ) )) == NULL) { printf( "Unable to allocate rank pdf array.\n" ); exit( 1 ); } make_zipf_distribution( fileset_list[i]->pdf, fileset_list[i]->num_files ); /* make_weibull_distribution( fileset_list[i]->pdf, fileset_list[i]->num_files ); */ } /* statistics about the number of views for each video */ typedef struct { rank_struct *rank_views; int num_unique; int num_multi; } session_view_stats_struct; session_view_stats_struct *session_viewstats, *svs; int fs_num; /* The goal of the next section is to ensure that files are assigned in */ /* strict rank order. That is, a file with a higher rank number should */ /* never be viewed more times than one with a lower rank number. */ /* Note that we need to track rank information for each different */ /* fileset. We also track the number of videos that are viewed only */ /* once. */ /* create storage for viewing statistics */ if ((session_viewstats = calloc( num_filesets, sizeof( session_view_stats_struct ) )) == NULL) { printf( "Unable to allocate session_view_stats array.\n" ); exit( 1 ); } for (i=0;inum_files + 1, sizeof( rank_struct ) )) == NULL) { printf( "Unable to allocate rank_views array.\n" ); exit( 1 ); } for (j=0;j <= fileset_list[i]->num_files; ++j) { session_viewstats[i].rank_views[j].index = j; } session_viewstats[i].num_unique = 0; session_viewstats[i].num_multi = 0; } /* create a list of session */ if ((session_info = calloc( num_sessions, sizeof( session_info_struct ) )) == NULL) { printf( "Unable to allocate session_info array.\n" ); exit( 1 ); } /* select a random set of ranks from the sample information */ for (i=0;i < num_sessions;++i) { session_info[i].client_id = i % num_log_files; /* choose fileset */ fs_num = 0; fileset_info = fileset_list[fs_num]; session_info[i].fsi = fileset_info; svs = &session_viewstats[fs_num]; double p; /* pick a random number and use to pick a sample rank */ p = random() / (1.0 + INT_MAX); for (rank=0; rank < fileset_info->num_files; ++rank) { p -= fileset_info->pdf[rank]; if (p < 0.0) { break; } } /* update viewing stats */ if (svs->rank_views[rank].num_views == 0) { svs->num_unique++; } else if (svs->rank_views[rank].num_views == 1) { svs->num_multi++; } session_info[i].rank = rank; svs->rank_views[rank].num_views++; } rank_struct *rank_unsorted; char dist_filename[100]; num_ranks = 0; total_num_multi = 0; for (fs_num=0;fs_numli->num_warm_files > svs->num_multi) fileset_info->li->num_warm_files = svs->num_multi; else if (fileset_info->li->num_warm_files > svs->num_unique) fileset_info->li->num_warm_files = svs->num_unique; /* copy the unsorted ranks */ if ((rank_unsorted = malloc( (fileset_info->num_files + 1) * sizeof( rank_struct ) )) == NULL) { printf( "Unable to allocate rank_unsorted array.\n" ); exit( 1 ); } memcpy( rank_unsorted, svs->rank_views, (fileset_info->num_files + 1) * sizeof( rank_struct ) ); /* sort the rank array by number of views */ qsort( svs->rank_views, fileset_info->num_files, sizeof( rank_struct ), compare_rank_views ); /* output the distribution by rank */ if (fs_num == 0) strcpy( dist_filename, "distribution.txt" ); else { //snprintf( dist_filename, sizeof( dist_filename ), "dist%d.txt", fs_num ); strcpy( dist_filename, "distribution.txt" ); dist_filename[11] = '0' + fs_num; } if ((f = fopen( dist_filename, "w" )) == NULL) { printf( "Error opening file %d\n", errno ); exit( 1 ); } fprintf( f, "# video_rank num_sessions unsorted_num_sessions\n" ); i=0; for (rank=0; rank < svs->num_unique; ++rank) { assert( svs->rank_views[rank].num_views > 0 ); fprintf( f, "%d %d", rank + 1, svs->rank_views[rank].num_views ); /* also output number of views from the unsorted list */ while (i < fileset_info->num_files && rank_unsorted[i].num_views == 0) { i++; } fprintf( f, " %d\n", rank_unsorted[i].num_views ); i++; } fclose( f ); free( rank_unsorted ); /* change the indices for the videos to match the sorted rank order */ for (i=0;i < num_sessions;++i) { /* process only the current fileset */ if (session_info[i].fsi == fileset_info) { for (rank=0; rank < fileset_info->num_files; ++rank) { if (svs->rank_views[rank].index == session_info[i].rank) { session_info[i].rank = rank; break; } } assert( rank < fileset_info->num_files ); } } num_ranks += svs->num_unique; total_num_multi += svs->num_multi; } /* for (fs_num=0;fs_numfi[ fileset_info->video_index[ rank ] ]); /* determine how long the video will be viewed */ frac = compute_session_frac( random() / (1.0 + INT_MAX) ); duration = session_info[i].fi->video_dur * frac; if (session_time_chunking > 1) { /* round to nearest chunk size */ if (duration < session_time_chunking) session_info[i].duration = duration; else session_info[i].duration = (int) (duration / session_time_chunking + 0.5) * session_time_chunking; } else { session_info[i].duration = duration; } total_session_time += duration; sum_session_time[rank] += duration; if (max_session_time[rank] < session_info[i].duration) { max_session_time[rank] = session_info[i].duration; } if (frac < 1.0) { session_histogram_points++; j = (int) (duration / SESSION_HISTOGRAM_BINSIZE); if (j < SESSION_HISTOGRAM_SIZE) { session_histogram[ j ]++; } else { session_histogram[ SESSION_HISTOGRAM_SIZE - 1 ]++; } } } /* output the histogram of session lengths */ double total_frac; f = fopen( "session_histogram.txt", "w" ); if (f == NULL) { printf( "Error opening file %d\n", errno ); exit( 1 ); } fprintf( f, "# session_time PDF CDF\n" ); fprintf( f, "# histogram num points = %d of %d\n", session_histogram_points, num_sessions ); total_frac = 0.0; for (i=0;ivideo_rank[i]; library_duration += fileset_info->fi[i].video_dur; /* round time if specified */ if (video_time_chunking > 1) { duration = ceil( fileset_info->fi[i].video_dur / video_time_chunking ) * video_time_chunking; } else { duration = fileset_info->fi[i].video_dur; } if (rank < num_ranks) { fprintf( f, "%05d %9.0f %8.1f %8.1f %8d %8.1f\n", i, duration * (fileset_info->file_MB_rate * BYTES_PER_MB), fileset_info->fi[i].video_dur, max_session_time[rank], rank, sum_session_time[rank] ); } else { fprintf( f, "%05d %9.0f %8.1f %8.1f %8d %8.1f\n", i, duration * (fileset_info->file_MB_rate * BYTES_PER_MB), fileset_info->fi[i].video_dur, 0.0, rank, 0.0 ); } } fclose( f ); /* create cumulative total of video memory requirements, in rank order */ f = fopen( "memory.txt", "w" ); if (f == NULL) { printf( "Error opening file %d\n", errno ); exit( 1 ); } fprintf( f, "# video_rank video_MB_CDF session_MB_CDF num_sessions_CDF video_MB_period\n" ); int total_sessions; int num_onetimers; total_unique_session_time = 0.0; total_duration = 0; total_sessions = 0; max_session = 0.0; num_onetimers = 0; fileset_info = fileset_list[0]; svs = &session_viewstats[0]; //for (i=0;inum_unique;++i) { if (max_session < max_session_time[i]) { max_session = max_session_time[i]; } total_unique_session_time += max_session_time[i]; total_duration += fileset_info->fi[ fileset_info->video_index[i] ].video_dur; total_sessions += svs->rank_views[i].num_views; if (svs->rank_views[i].num_views == 1) num_onetimers++; fprintf( f, "%d %.1f %.1f %.3f %.1f\n", i + 1, total_duration * fileset_info->file_MB_rate, total_unique_session_time * fileset_info->file_MB_rate, (double) total_sessions / num_sessions, average_video_MB / svs->rank_views[i].num_views * num_sessions ); } fclose( f ); /* write out the session fraction histogram */ if ((f = fopen( "session_frac_histogram.txt", "w" )) == NULL) { printf( "Error opening file %d\n", errno ); exit( 1 ); } fprintf( f, "# session_time_fraction session_CDF\n" ); total = 0; for (i=0;ili->file_seconds_per_request ); num_client_chunks_requested += num_requests; fprintf( f, "%d %.3f %.0f %d\n", session_info[i].rank + 1, session_info[i].duration, session_info[i].fsi->file_MB_rate, num_requests ); } fclose( f ); /* NOTE: clients choose from a number of videos. Each video has a different duration */ /* and each client watches the video for a different session time. */ /* The client requests the video content in a series of fixed-time requests. */ num_header_lines = 0; sprintf( header_line[num_header_lines++], "random seed = %ld", random_seed ); puts( header_line[num_header_lines-1] ); sprintf( header_line[num_header_lines++], "Zipf exponent = %0.4f", zipf_exponent ); puts( header_line[num_header_lines-1] ); sprintf( header_line[num_header_lines++], "number of videos in library = %d", library_size ); puts( header_line[num_header_lines-1] ); sprintf( header_line[num_header_lines++], "number of sessions = %d (%d x %d)", num_sessions, num_log_files, num_log_sessions ); puts( header_line[num_header_lines-1] ); printf( "\n" ); sprintf( header_line[num_header_lines++], "seconds of video per client request = %.2f s", fileset_list[0]->li->file_seconds_per_request ); puts( header_line[num_header_lines-1] ); sprintf( header_line[num_header_lines++], "size of client requests = %.2f MB", fileset_list[0]->li->client_MB_per_request ); puts( header_line[num_header_lines-1] ); sprintf( header_line[num_header_lines++], "file bit rate = %.3f Mbps", fileset_list[0]->file_MB_rate * (BYTES_PER_MB * 8) / 1000000 ); puts( header_line[num_header_lines-1] ); sprintf( header_line[num_header_lines++], "timeout for request delivery = %.2f s", timeout_per_request ); puts( header_line[num_header_lines-1] ); sprintf( header_line[num_header_lines++], "number of unpaced requests at session start = %d", num_buffering_requests ); puts( header_line[num_header_lines-1] ); printf( "\n" ); sprintf( header_line[num_header_lines++], "total number of unique videos = %d", num_ranks ); puts( header_line[num_header_lines-1] ); sprintf( header_line[num_header_lines++], "total size of library = %.0f MB", library_duration * fileset_list[0]->file_MB_rate ); puts( header_line[num_header_lines-1] ); sprintf( header_line[num_header_lines++], "total size of viewed videos = %.0f MB", total_duration * fileset_list[0]->file_MB_rate ); puts( header_line[num_header_lines-1] ); sprintf( header_line[num_header_lines++], "percentage of single-request videos = %.1f %%", 100.0 * num_onetimers / num_ranks ); puts( header_line[num_header_lines-1] ); sprintf( header_line[num_header_lines++], "average views per video = %.1f", (double) num_sessions / num_ranks ); puts( header_line[num_header_lines-1] ); sprintf( header_line[num_header_lines++], "average duration of videos = %.1f s", total_duration / num_ranks ); puts( header_line[num_header_lines-1] ); sprintf( header_line[num_header_lines++], "average size of videos = %.1f MB", average_video_MB ); puts( header_line[num_header_lines-1] ); printf( "\n" ); /* chart amount of memory required to store these numbers of videos */ /* make one of the sizes equal to the number of videos requested more than once */ static int chart_num_videos[] = { 5, 10, 50, 100, 500, 5000, 0, 0 }; i = 0; while (chart_num_videos[i] != 0) { i++; } chart_num_videos[i] = total_num_multi; i = 0; printf( "Top Video Popularity:\n" ); printf( "# files size (MB) percent of sessions\n" ); while (chart_num_videos[i] > 0) { total = 0; for (j=0;j= num_ranks) { break; } total += session_viewstats[0].rank_views[j].num_views; } printf( "%7d %9.1f %5.1f\n", j, j * average_video_MB, 100.0 * total / num_sessions ); i++; } printf( "\n" ); /* printf( "total time of sessions = %.0f s\n", total_session_time ); */ sprintf( header_line[num_header_lines++], "maximum session time = %.0f s", max_session ); puts( header_line[num_header_lines-1] ); sprintf( header_line[num_header_lines++], "maximum number of client requests in session = %.0f", max_session / fileset_list[0]->li->file_seconds_per_request ); puts( header_line[num_header_lines-1] ); /* printf( "total time of unique requests = %.0f s\n", total_unique_session_time ); */ sprintf( header_line[num_header_lines++], "total number of client requests = %d", num_client_chunks_requested ); puts( header_line[num_header_lines-1] ); double chunks_per_session; chunks_per_session = (double) num_client_chunks_requested / num_sessions; printf( "\n" ); sprintf( header_line[num_header_lines++], "average duration of session = %.1f s", total_session_time / num_sessions ); puts( header_line[num_header_lines-1] ); sprintf( header_line[num_header_lines++], "average size of session = %.1f MB", chunks_per_session * fileset_list[0]->li->client_MB_per_request ); puts( header_line[num_header_lines-1] ); sprintf( header_line[num_header_lines++], "average client requests per session = %.3f", chunks_per_session ); puts( header_line[num_header_lines-1] ); assert( num_header_lines <= MAX_HEADER_LINES ); create_log_files( session_info, num_videos ); printf( "\n" ); static int req_sizes[] = { 5, 10, 20, 50, 100, 200, 500, 750, 900, 0 }; i = 0; printf( "Experiment statistics:\n" ); printf( "req/s Mbps Time (minutes)\n" ); while (req_sizes[i] > 0) { printf( "%5d %6.0f %7.1f\n", req_sizes[i], req_sizes[i] * fileset_list[0]->li->client_MB_per_request * 8, (double) num_client_chunks_requested / req_sizes[i] / 60 ); i++; } return( 0 ); } /* Helper function for the qsort() routine. We want to sort the chunk uses * in descending order, so return a negative number when the first item is * larger than the second. */ typedef struct { int file_number; /* id number for this file */ int owner_rank; /* rank of video that uses this chunk */ int num_uses; /* number of times this chunk is used */ int order; /* order that chunks are seen the first time */ } request_info_struct; static int compare_chunk_uses( const void *c1, const void *c2 ) { return( ((request_info_struct *) c2)->num_uses - ((request_info_struct *) c1)->num_uses ); } /* Helper function for the qsort() routine. This sorts chunk id * ascending order. */ static int compare_file_numbers( const void *c1, const void *c2 ) { return( ((request_info_struct *) c1)->file_number - ((request_info_struct *) c2)->file_number ); } /* Helper function for the qsort() routine. This sorts chunks in the order that they * were first viewed. */ static int compare_chunk_order( const void *c1, const void *c2 ) { return( ((request_info_struct *) c1)->order - ((request_info_struct *) c2)->order ); } /* avoid making client chunks that are shorter than this number of bytes */ #define MINIMUM_CLIENT_CHUNK 100 /* Output a series of range requests needed to transfer the specified number of * bytes. The num_session_requests value counts the number of client chunks that * have been used for the session, and is used to control when pacing occurs. */ static void output_chunk_requests( FILE *f, fileset_info_struct *fsi, int rank, int *num_session_requests, int file_number, int request_num_bytes, int request_offset, int timeout, int pace_time ) { int offset, end; int chunk_end; char *basename; int client_byte_request_size; /* Note: there are two ways to interpret request offsets, either all requests are offset */ /* by this amount and are the same size as when the offset is 0, or the first request is */ /* offset, and the rest start on multiples of the client_byte_request_size (and the sizes */ /* of the first and last requests will be different than if the offset were 0. */ #ifdef FIXED_OFFSET offset = 0; #else offset = request_offset; request_num_bytes += request_offset; #endif if (rank < fsi->li->num_warm_files) basename = fsi->li->log_warm_basename; else basename = fsi->li->log_cold_basename; client_byte_request_size = fsi->li->client_MB_per_request * BYTES_PER_MB; /* assume HTTP ranges include the endpoints */ end = offset + client_byte_request_size - 1; /* output series of range requests using the client chunk size */ do { /* adjust size of final chunk */ if (end >= request_num_bytes - MINIMUM_CLIENT_CHUNK) { end = request_num_bytes - 1; chunk_end = end; } #ifdef VBR_CHUNKS else { /* adjust end of chunk to change chunk size by +- VBR_FACTOR */ chunk_end = end + (2 * VBR_FACTOR * random() / (1.0 + INT_MAX) - VBR_FACTOR) * client_byte_request_size; /* if chunk extends beyond end of file, adjust size */ if (chunk_end > request_num_bytes - MINIMUM_CLIENT_CHUNK) { /* make chunk half as big, if possible */ chunk_end = (chunk_end + offset) / 2; if (chunk_end > request_num_bytes - MINIMUM_CLIENT_CHUNK) { chunk_end = request_num_bytes - 1; } } } #else chunk_end = end; #endif //printf( "chunk: offset %d chunk_end %d end %d blk_size %.2f %%\n", offset, chunk_end, end, 100.0 * (chunk_end - offset) / client_byte_request_size ); /* make name like: /affinity_set_small2/100Mb-02011.txt */ /* NOTE: Apache reports a "Bad Request" if the leading '/' is missing from URIs */ (*num_session_requests)++; #ifdef FIXED_OFFSET if (*num_session_requests > num_buffering_requests) fprintf( f, "/%s-%0*d.mp4 pace_time=%d timeout=%d headers='Range: bytes=%d-%d'\n", basename, fsi->li->fname_num_digits, file_number, pace_time, timeout, offset + request_offset, chunk_end + request_offset ); else fprintf( f, "/%s-%0*d.mp4 timeout=%d headers='Range: bytes=%d-%d'\n", basename, fsi->li->fname_num_digits, file_number, timeout, offset + request_offset, chunk_end + request_offset ); #else if (*num_session_requests > num_buffering_requests) fprintf( f, "/%s-%0*d.mp4 pace_time=%d timeout=%d headers='Range: bytes=%d-%d'\n", basename, fsi->li->fname_num_digits, file_number, pace_time, timeout, offset, chunk_end ); else fprintf( f, "/%s-%0*d.mp4 timeout=%d headers='Range: bytes=%d-%d'\n", basename, fsi->li->fname_num_digits, file_number, timeout, offset, chunk_end ); #endif offset = chunk_end + 1; end += client_byte_request_size; } while (offset < request_num_bytes); } static int create_log_files( session_info_struct *session_info, int total_num_videos ) { int *num_log_requests; char out_fname[200]; int file_number; FILE *f; int i, j; int s; request_info_struct *request_info; int single_chunk; int num_chunks_used; logfile_info_struct *log_info; if ((num_log_requests = calloc( num_log_files, sizeof( int ) )) == NULL) { printf( "Unable to allocate num_log_requests array.\n" ); exit( 1 ); } /* compute number of requests in each log file */ printf( "client requests per log file: " ); s = 0; for (j=0; j < num_log_sessions; ++j) { for (i=0; i < num_log_files; ++i) { num_log_requests[i] += ceil( session_info[s].duration / session_info[s].fsi->li->file_seconds_per_request ); s++; } } for (i=0; i < num_log_files; ++i) { printf( " %d", num_log_requests[i] ); } printf( "\n" ); /* array to determine the popularity of different videos */ if ((request_info = calloc( total_num_videos, sizeof( request_info_struct ) )) == NULL) { printf( "Unable to allocate request_info array.\n" ); exit( 1 ); } for (i=0;ivideo_rank[i]; } /* create log files to hold the requests. */ double timeout; int request_bytes; int request_offset; int video_order = 0; int num_session_requests; double sess_time; for (i=0; i < num_log_files; ++i) { /* create a name like: cl-zipf4-2500-10-300-00.log */ snprintf( out_fname, sizeof( out_fname ), "%s-%s-%d-%.0f-%.0f-%d-%02d.log", log_basename, video_quality_str, num_videos, 5000.0 / fileset_list[0]->li->client_MB_per_request, fileset_list[0]->li->file_seconds_per_request, num_log_sessions, i ); f = fopen( out_fname, "w" ); if (f == NULL) { printf( "Error opening file %d\n", errno ); exit( 1 ); } /* add header to log file */ for (j=0; j < num_header_lines; ++j) { fprintf( f, "# %s\n", header_line[j] ); } fprintf( f, "# number of chunks in log file = %d\n", num_log_requests[i] ); fprintf( f, "# average chunks per session in log file = %.2f\n", (double) num_log_requests[i] / num_log_sessions ); /* go through session information, finding sessions for this client */ s = 0; for (;;) { /* find next session with matching client */ //while (session_info[s].client_id != i) { if (s >= num_sessions) { /* break out of this loop and outer loop */ goto next_client; } //} /* determine video file number and time for session */ file_number = session_info[s].fi->file_number; sess_time = session_info[s].duration; /* adjust timeout based on session time */ if (timeout_per_request > sess_time) { timeout = sess_time; } else { timeout = timeout_per_request; } if (timeout < min_timeout) timeout = min_timeout; /* determine size of session in bytes as well as the file size */ /* and adjust offset accordingly. */ request_bytes = sess_time * session_info[s].fsi->file_MB_rate * BYTES_PER_MB; num_session_requests = 0; #if defined( FIXED_OFFSET ) | defined( MIDPOINT_OFFSET ) | defined( ENDPOINT_OFFSET ) int file_size; file_size = session_info[s].fi->size; #endif #if defined( FIXED_OFFSET ) if (file_size - request_bytes > FIXED_OFFSET_BYTES) { request_offset = FIXED_OFFSET_BYTES; } else { request_offset = 0; } #elif defined( MIDPOINT_OFFSET ) request_offset = (file_size - request_bytes) / 2; #elif defined( ENDPOINT_OFFSET ) request_offset = file_size - request_bytes; #else request_offset = 0; #endif /* output a sequence of range requests to read this video */ output_chunk_requests( f, session_info[s].fsi, session_info[s].rank, &num_session_requests, file_number, request_bytes, request_offset, (int) timeout, (int) timeout_per_request ); request_info[file_number].num_uses++; request_info[file_number].order = ++video_order; /* mark end of session */ fputs( "\n", f ); /* look at next session */ s++; } next_client: fclose( f ); } /* sort the chunk array by order first viewed */ qsort( request_info, total_num_videos, sizeof( request_info[0] ), compare_chunk_order ); /* output file consisting of all one-timer chunks, in the order they occur */ f = fopen( "one_time_chunks.log", "w" ); if (f == NULL) { printf( "Error opening file %d\n", errno ); exit( 1 ); } for (i=0;ili; fprintf( f, "%s-%0*d.txt\n", log_info->log_cold_basename, log_info->fname_num_digits, file_number ); } } fclose( f ); /* sort the chunk array by number of uses */ qsort( request_info, total_num_videos, sizeof( request_info[0] ), compare_chunk_uses ); /* output chunk information for plotting and compute the fraction of */ /* all requests that appear in the warming file. */ int total_num_requests; f = fopen( "chunk_use.txt", "w" ); if (f == NULL) { printf( "Error opening file %d\n", errno ); exit( 1 ); } fprintf( f, "# chunk_id chunk_frequency video_rank\n" ); total_num_requests = 0; single_chunk = total_num_videos; num_chunks_used = total_num_videos; for (i=0;ili->num_warm_files; snprintf( out_fname, sizeof( out_fname ), "%s-%d-%.0f-%d-%d-warm", preload_basename, num_videos, 5000.0 / fileset_list[0]->li->client_MB_per_request, num_log_sessions, num_warm_chunks ); f = fopen( out_fname, "w" ); if (f == NULL) { printf( "Error opening file %d\n", errno ); exit( 1 ); } /* sort the warm chunks by chunk id to make preloading faster */ int num_warm_requests = 0; qsort( request_info, num_warm_chunks, sizeof( request_info[0] ), compare_file_numbers ); for (i=0; i < num_warm_chunks; ++i) { file_number = request_info[i].file_number; log_info = fileset_list[0]->li; fprintf( f, "%s-%0*d.txt\n", log_info->log_warm_basename, log_info->fname_num_digits, file_number ); num_warm_requests += request_info[i].num_uses; } fclose( f ); printf( "number of chunks to preload = %d\n", num_warm_chunks ); printf( "percent of chunk requests preloaded = %.1f %%", 100.0 * num_warm_requests / total_num_requests ); /* output file with all the cold chunks */ snprintf( out_fname, sizeof( out_fname ), "%s-%d-%.0f-%d-%d-cold", preload_basename, num_videos, 5000.0 / fileset_list[0]->li->client_MB_per_request, num_log_sessions, num_warm_chunks ); f = fopen( out_fname, "w" ); if (f == NULL) { printf( "Error opening file %d\n", errno ); exit( 1 ); } /* sort the cold chunks by chunk id */ if (num_warm_chunks < num_chunks_used) { qsort( request_info + num_warm_chunks, num_chunks_used - num_warm_chunks, sizeof( request_info[0] ), compare_file_numbers ); for (i=num_warm_chunks; i < num_chunks_used; ++i) { file_number = request_info[i].file_number; log_info = fileset_list[0]->li; fprintf( f, "%s-%0*d.txt\n", log_info->log_cold_basename, log_info->fname_num_digits, file_number ); } } fclose( f ); return( 0 ); } ================================================ FILE: benchmarks/media-streaming/dataset/files/filegen/params/240p ================================================ library_size=10 num_log_files=1 num_log_sessions=5 video_quality=240p ================================================ FILE: benchmarks/media-streaming/dataset/files/filegen/params/360p ================================================ library_size=10 num_log_files=1 num_log_sessions=5 video_quality=360p ================================================ FILE: benchmarks/media-streaming/dataset/files/filegen/params/480p ================================================ library_size=10 num_log_files=1 num_log_sessions=5 video_quality=480p ================================================ FILE: benchmarks/media-streaming/dataset/files/filegen/params/720p ================================================ library_size=10 num_log_files=1 num_log_sessions=5 video_quality=720p ================================================ FILE: benchmarks/media-streaming/dataset/files/filegen/video_gen.py ================================================ import re from subprocess import call import os from sys import argv from random import randint video_io_filenames ={} config_param_path = None video_file_info_path = None textpaths_dir = None output_videos_dir = None file_resolution_info = None videos_path = None videos_js_path = None def bytes_to_MB(number_of_bytes): factor = 1024*1024 number_of_bytes = float(number_of_bytes) number_of_bytes /= factor precision = 1 number_of_bytes = round(number_of_bytes, precision) return number_of_bytes def generate_video_file_with_requested_size(requested_video_size_in_bytes,input_file_path,resolution,output_video_name): file_stats = os.stat(input_file_path) actual_file_size_bytes = int(file_stats.st_size) size_diff = int(bytes_to_MB(actual_file_size_bytes)) - int(bytes_to_MB(requested_video_size_in_bytes)) if size_diff < 0: num_concatenations = int(requested_video_size_in_bytes / actual_file_size_bytes) + 1 else: num_concatenations = 1 output_file_name = os.path.splitext(output_video_name)[0] in_txt_file_path = textpaths_dir + output_file_name + ".txt" out_mp4_file_path = output_videos_dir + str(output_video_name) video_io_filenames[in_txt_file_path] = out_mp4_file_path input_file_path = input_file_path in_file = open(in_txt_file_path, "a+") for num in range(int(num_concatenations)): in_file.write("file " + "'" + input_file_path + "'\n") def get_resolution(): f = open(file_resolution_info, 'r') resolution = None for line in f: if "video_quality" in line: resolution = line.split("=")[1] f.close() resolution = resolution.strip() return resolution def getopts(argv): opts = {} while argv: if argv[0][0] == '-': opts[argv[0]] = argv[1] argv = argv[1:] return opts def get_video_info(): video_request_dict = {} f = open(video_file_info_path, 'r') video_names_list = [] for line in f: line = re.sub('[ \t]+', ' ', line) if line[0] != "#": video_info = line.split(" ") size = int(video_info[1]) video_request_dict[video_info[0]] = size video_names_list.append(video_info[0]) f.close() return video_request_dict,video_names_list def parse_videos_info(resolution,videos_path): input_video_collection = [] complete_path = videos_path+"/"+resolution+"/" for file in os.listdir(complete_path): if file.endswith(".mp4"): input_video_collection.append(os.path.join(complete_path, file)) return input_video_collection if __name__ == '__main__': myargs = getopts(argv) if '-p' not in myargs or '-v' not in myargs or '-s' not in myargs or '-o' not in myargs: raise ValueError('Please provide a valid config files.') exit(1) else: file_resolution_info = myargs["-p"] video_file_info_path = myargs["-v"] videos_path = myargs["-s"] output_videos_dir = myargs["-o"] textpaths_dir = "/tmp/textpaths/" videos_js_path = output_videos_dir+"/"+"test_videos.js" resolution = get_resolution() if resolution is None: raise ValueError('Please provide a valid config param file.') exit(1) input_video_collection = parse_videos_info(resolution,videos_path) video_request_dict,video_names_list = get_video_info() videos_js_file = open(videos_js_path,"a+") videos_list_in_js = "" for key in video_names_list: output_video_name = "full-"+resolution+"-"+key+".mp4" requested_video_size_in_bytes = video_request_dict[key] local_file_path = input_video_collection[0] del input_video_collection[0] input_video_collection.append(local_file_path) generate_video_file_with_requested_size(requested_video_size_in_bytes,local_file_path,resolution,output_video_name) videos_list_in_js = videos_list_in_js+'"'+output_video_name+'",' videos_js_file.write("var videos"+resolution+" = [" +videos_list_in_js[:-1]+"]\n") # Execute ffmpeg to concatenate these input videos to get output videos of required sizes for in_txt_filename in video_io_filenames.keys(): ffmpeg_cmd = "ffmpeg -y -loglevel error -f concat -safe 0 -i " + in_txt_filename + " -c copy " + video_io_filenames.get(in_txt_filename); call(ffmpeg_cmd, shell=True) ================================================ FILE: benchmarks/media-streaming/server/Dockerfile ================================================ FROM cloudsuite/base-os:ubuntu RUN apt-get update -y \ && apt-get install -y --no-install-recommends nginx openssl \ && rm -rf /var/lib/apt/lists/* # Increase the open file limit COPY files/limits.conf.append /tmp/ RUN cat /tmp/limits.conf.append >> /etc/security/limits.conf COPY files/nginx.location.append /tmp/ RUN cat /tmp/nginx.location.append > /etc/nginx/sites-available/default COPY files/HTMLWebPlayer /usr/share/nginx/html/HTMLWebPlayer # Update nginx to serve /videos #RUN sed -i 's|/usr/share/nginx/html|/videos|g' /etc/nginx/sites-available/default COPY entrypoint.sh /etc/entrypoint.sh RUN chown root:root /etc/entrypoint.sh RUN chmod 700 /etc/entrypoint.sh ENTRYPOINT ["/etc/entrypoint.sh"] ================================================ FILE: benchmarks/media-streaming/server/entrypoint.sh ================================================ #!/bin/bash cd /etc/nginx openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout media_streaming_CS_4.key -out media_streaming_CS_4.crt -subj '/C=CH/ST=VD/L=Lausanne/CN=www.mediaStreamingCS4.com' WORKER_CONNECTIONS="${1:-2000}" sed -i "s/worker_connections \([0-9]*\);/worker_connections ${WORKER_CONNECTIONS};/g" /etc/nginx/nginx.conf nginx -g 'daemon off;' ================================================ FILE: benchmarks/media-streaming/server/files/HTMLWebPlayer/index.html ================================================ CloudSuite Media Streaming Benchmark
Available videos in each resolution
================================================ FILE: benchmarks/media-streaming/server/files/HTMLWebPlayer/js/helper.js ================================================ function populateVideosList(selectedList) { var size = Math.min(selectedList.length, 10) for (i = 0; i < size; ++i) { $('#videolist').append($('