From 4861bb817645893f15313e0e832a0c75e1916d5a Mon Sep 17 00:00:00 2001 From: menderico Date: Tue, 29 Sep 2009 00:31:36 +0000 Subject: [PATCH] Initial commit --- COPYING | 201 + Makefile.am | 2 + Makefile.in | 628 +++ aclocal.m4 | 868 ++++ config.guess | 1516 ++++++ config.sub | 1626 +++++++ configure | 8279 +++++++++++++++++++++++++++++++++ configure.ac | 111 + depcomp | 589 +++ install-sh | 519 +++ missing | 367 ++ src/Makefile.am | 31 + src/Makefile.in | 476 ++ src/adler32memcpy.cc | 380 ++ src/adler32memcpy.h | 59 + src/disk_blocks.cc | 313 ++ src/disk_blocks.h | 115 + src/error_diag.cc | 317 ++ src/error_diag.h | 167 + src/finelock_queue.cc | 441 ++ src/finelock_queue.h | 116 + src/logger.cc | 151 + src/logger.h | 142 + src/main.cc | 56 + src/os.cc | 642 +++ src/os.h | 265 ++ src/os_factory.cc | 41 + src/pattern.cc | 421 ++ src/pattern.h | 124 + src/queue.cc | 118 + src/queue.h | 85 + src/sat.cc | 1897 ++++++++ src/sat.h | 309 ++ src/sat_factory.cc | 21 + src/sattypes.h | 156 + src/stressapptest_config.h.in | 188 + src/worker.cc | 3258 +++++++++++++ src/worker.h | 782 ++++ 38 files changed, 25777 insertions(+) create mode 100644 COPYING create mode 100644 Makefile.am create mode 100644 Makefile.in create mode 100644 aclocal.m4 create mode 100755 config.guess create mode 100755 config.sub create mode 100755 configure create mode 100644 configure.ac create mode 100755 depcomp create mode 100755 install-sh create mode 100755 missing create mode 100644 src/Makefile.am create mode 100644 src/Makefile.in create mode 100644 src/adler32memcpy.cc create mode 100644 src/adler32memcpy.h create mode 100644 src/disk_blocks.cc create mode 100644 src/disk_blocks.h create mode 100644 src/error_diag.cc create mode 100644 src/error_diag.h create mode 100644 src/finelock_queue.cc create mode 100644 src/finelock_queue.h create mode 100644 src/logger.cc create mode 100644 src/logger.h create mode 100644 src/main.cc create mode 100644 src/os.cc create mode 100644 src/os.h create mode 100644 src/os_factory.cc create mode 100644 src/pattern.cc create mode 100644 src/pattern.h create mode 100644 src/queue.cc create mode 100644 src/queue.h create mode 100644 src/sat.cc create mode 100644 src/sat.h create mode 100644 src/sat_factory.cc create mode 100644 src/sattypes.h create mode 100644 src/stressapptest_config.h.in create mode 100644 src/worker.cc create mode 100644 src/worker.h diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..8b9312d --- /dev/null +++ b/COPYING @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2008 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..823c209 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,2 @@ +SUBDIRS = src +dist_doc_DATA = COPYING \ No newline at end of file diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..608e89c --- /dev/null +++ b/Makefile.in @@ -0,0 +1,628 @@ +# Makefile.in generated by automake 1.10.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = . +DIST_COMMON = $(am__configure_deps) $(dist_doc_DATA) \ + $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/configure COPYING config.guess config.sub \ + depcomp install-sh missing +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/src/stressapptest_config.h +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(docdir)" +dist_docDATA_INSTALL = $(INSTALL_DATA) +DATA = $(dist_doc_DATA) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + { test ! -d $(distdir) \ + || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -fr $(distdir); }; } +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = src +dist_doc_DATA = COPYING +all: all-recursive + +.SUFFIXES: +am--refresh: + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign '; \ + cd $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +install-dist_docDATA: $(dist_doc_DATA) + @$(NORMAL_INSTALL) + test -z "$(docdir)" || $(MKDIR_P) "$(DESTDIR)$(docdir)" + @list='$(dist_doc_DATA)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(dist_docDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(docdir)/$$f'"; \ + $(dist_docDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(docdir)/$$f"; \ + done + +uninstall-dist_docDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_doc_DATA)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(docdir)/$$f'"; \ + rm -f "$(DESTDIR)$(docdir)/$$f"; \ + done + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d $(distdir) || mkdir $(distdir) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + distdir=`$(am__cd) $(distdir) && pwd`; \ + top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ + (cd $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$top_distdir" \ + distdir="$$distdir/$$subdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + distdir) \ + || exit 1; \ + fi; \ + done + -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r $(distdir) +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-lzma: distdir + tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lzma*) \ + unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && cd $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @cd $(distuninstallcheck_dir) \ + && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile $(DATA) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(docdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +info: info-recursive + +info-am: + +install-data-am: install-dist_docDATA + +install-dvi: install-dvi-recursive + +install-exec-am: + +install-html: install-html-recursive + +install-info: install-info-recursive + +install-man: + +install-pdf: install-pdf-recursive + +install-ps: install-ps-recursive + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-dist_docDATA + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ + install-strip + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am am--refresh check check-am clean clean-generic \ + ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \ + dist-lzma dist-shar dist-tarZ dist-zip distcheck distclean \ + distclean-generic distclean-tags distcleancheck distdir \ + distuninstallcheck dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am \ + install-dist_docDATA install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ + pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \ + uninstall-dist_docDATA + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..eb3b99a --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,868 @@ +# generated automatically by aclocal 1.10.1 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(AC_AUTOCONF_VERSION, [2.61],, +[m4_warning([this file was generated for autoconf 2.61. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically `autoreconf'.])]) + +# Copyright (C) 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.10' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.10.1], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.10.1])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(AC_AUTOCONF_VERSION)]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 8 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 9 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], UPC, [depcc="$UPC" am_compiler_list=], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +#serial 3 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 13 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.60])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_PROG_INSTALL_SH +AM_PROG_INSTALL_STRIP +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl +]) +]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"} +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_MKDIR_P +# --------------- +# Check for `mkdir -p'. +AC_DEFUN([AM_PROG_MKDIR_P], +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + diff --git a/config.guess b/config.guess new file mode 100755 index 0000000..278f9e9 --- /dev/null +++ b/config.guess @@ -0,0 +1,1516 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, +# Inc. + +timestamp='2007-07-22' + +# 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., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, 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. + + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# 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 build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +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 + +# 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. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + 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 + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # 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 ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # 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. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit ;; + 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 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + 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 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + 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 ;; + 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 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /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 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # 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 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + 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 -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + 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 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????: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 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + 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 ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${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=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + 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 -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + 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 -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:[3456]*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + EM64T | authenticamd) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 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 i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + xtensa:Linux:*:*) + echo xtensa-unknown-linux-gnu + exit ;; + i*86: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. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^LIBC/{ + s: ::g + p + }'`" + test x"${LIBC}" != x && { + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit + } + test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } + ;; + i*86:DYNIX/ptx:4*:*) + # 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. + echo i386-sequent-sysv4 + exit ;; + 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 ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + 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 ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + 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|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + 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 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + 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 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*: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; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *: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 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + 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 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *: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 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +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\n"); 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) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# 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 -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# 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 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +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: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.sub b/config.sub new file mode 100755 index 0000000..1761d8b --- /dev/null +++ b/config.sub @@ -0,0 +1,1626 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, +# Inc. + +timestamp='2007-06-28' + +# 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., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, 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 . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# 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 + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + 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* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ + uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + 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 | -knuth | -cray) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -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/'` + ;; + -sco5v6*) + # 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. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | mt \ + | msp430 \ + | nios | nios2 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | score \ + | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k) + 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 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + # 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*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. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # 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 + ;; + abacus) + basic_machine=abacus-unknown + ;; + 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 + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + 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 + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + 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 | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + 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 + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + 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*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*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 + ;; + 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 + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + 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 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + 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 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-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/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-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=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + 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 + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + 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 + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + 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 + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + 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* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -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 + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -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[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -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 + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + 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 + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-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 + ;; + f30[01]-fujitsu | f700-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 + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure b/configure new file mode 100755 index 0000000..1dcc6f3 --- /dev/null +++ b/configure @@ -0,0 +1,8279 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.61 for stressapptest 1.0.0_autoconf. +# +# Report bugs to . +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + +if test "x$CONFIG_SHELL" = x; then + if (eval ":") 2>/dev/null; then + as_have_required=yes +else + as_have_required=no +fi + + if test $as_have_required = yes && (eval ": +(as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=\$LINENO + as_lineno_2=\$LINENO + test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && + test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } +") 2> /dev/null; then + : +else + as_candidate_shells= + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + case $as_dir in + /*) + for as_base in sh bash ksh sh5; do + as_candidate_shells="$as_candidate_shells $as_dir/$as_base" + done;; + esac +done +IFS=$as_save_IFS + + + for as_shell in $as_candidate_shells $SHELL; do + # Try only shells that exist, to save several forks. + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { ("$as_shell") 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +_ASEOF +}; then + CONFIG_SHELL=$as_shell + as_have_required=yes + if { "$as_shell" 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +(as_func_return () { + (exit $1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = "$1" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test $exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } + +_ASEOF +}; then + break +fi + +fi + + done + + if test "x$CONFIG_SHELL" != x; then + for as_var in BASH_ENV ENV + do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + done + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + + if test $as_have_required = no; then + echo This script requires a shell more modern than all the + echo shells that I found on your system. Please install a + echo modern shell, or manually run the script under such a + echo shell if you do have one. + { (exit 1); exit 1; } +fi + + +fi + +fi + + + +(eval "as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0") || { + echo No shell found that supports shell functions. + echo Please tell autoconf@gnu.org about your system, + echo including any error possibly output before this + echo message +} + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + + +exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Identity of this package. +PACKAGE_NAME='stressapptest' +PACKAGE_TARNAME='stressapptest' +PACKAGE_VERSION='1.0.0_autoconf' +PACKAGE_STRING='stressapptest 1.0.0_autoconf' +PACKAGE_BUGREPORT='opensource@gmail.com' + +ac_unique_file="src/" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='SHELL +PATH_SEPARATOR +PACKAGE_NAME +PACKAGE_TARNAME +PACKAGE_VERSION +PACKAGE_STRING +PACKAGE_BUGREPORT +exec_prefix +prefix +program_transform_name +bindir +sbindir +libexecdir +datarootdir +datadir +sysconfdir +sharedstatedir +localstatedir +includedir +oldincludedir +docdir +infodir +htmldir +dvidir +pdfdir +psdir +libdir +localedir +mandir +DEFS +ECHO_C +ECHO_N +ECHO_T +LIBS +build_alias +host_alias +target_alias +build +build_cpu +build_vendor +build_os +host +host_cpu +host_vendor +host_os +target +target_cpu +target_vendor +target_os +INSTALL_PROGRAM +INSTALL_SCRIPT +INSTALL_DATA +am__isrc +CYGPATH_W +PACKAGE +VERSION +ACLOCAL +AUTOCONF +AUTOMAKE +AUTOHEADER +MAKEINFO +install_sh +STRIP +INSTALL_STRIP_PROGRAM +mkdir_p +AWK +SET_MAKE +am__leading_dot +AMTAR +am__tar +am__untar +CXX +CXXFLAGS +LDFLAGS +CPPFLAGS +ac_ct_CXX +EXEEXT +OBJEXT +DEPDIR +am__include +am__quote +AMDEP_TRUE +AMDEP_FALSE +AMDEPBACKSLASH +CXXDEPMODE +am__fastdepCXX_TRUE +am__fastdepCXX_FALSE +CC +CFLAGS +ac_ct_CC +CCDEPMODE +am__fastdepCC_TRUE +am__fastdepCC_FALSE +CPP +GREP +EGREP +LIBOBJS +LTLIBOBJS' +ac_subst_files='' + ac_precious_vars='build_alias +host_alias +target_alias +CXX +CXXFLAGS +LDFLAGS +LIBS +CPPFLAGS +CCC +CC +CFLAGS +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +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=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -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_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$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 ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + 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 | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$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 ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + 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 | -n) + 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 ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$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_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=\$ac_optarg ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + 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 "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute directory names. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; } +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + { echo "$as_me: error: Working directory cannot be determined" >&2 + { (exit 1); exit 1; }; } +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + { echo "$as_me: error: pwd does not report name of working directory" >&2 + { (exit 1); exit 1; }; } + + +# 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 the parent directory. + ac_confdir=`$as_dirname -- "$0" || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + 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 + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 + { (exit 1); exit 1; }; } + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # 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 <<_ACEOF +\`configure' configures stressapptest 1.0.0_autoconf to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/stressapptest] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --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 + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] + --target=TARGET configure for building compilers for TARGET [HOST] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of stressapptest 1.0.0_autoconf:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + +Some influential environment variables: + CXX C++ compiler command + CXXFLAGS C++ compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CC C compiler command + CFLAGS C compiler flags + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +stressapptest configure 1.0.0_autoconf +generated by GNU Autoconf 2.61 + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by stressapptest $as_me 1.0.0_autoconf, which was +generated by GNU Autoconf 2.61. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +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 || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args '$ac_arg'" + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------------- ## +## File substitutions. ## +## ------------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -n "$CONFIG_SITE"; then + set x "$CONFIG_SITE" +elif test "x$prefix" != xNONE; then + set x "$prefix/share/config.site" "$prefix/etc/config.site" +else + set x "$ac_default_prefix/share/config.site" \ + "$ac_default_prefix/etc/config.site" +fi +shift +for ac_site_file +do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + + + + + + + + + + + + + + + + + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +# Checking for target cpu and setting custom configuration +# for the different platforms +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 + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 +echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} + { (exit 1); exit 1; }; } +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 +echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;} + { (exit 1); exit 1; }; } + +{ echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6; } +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5 +echo "$as_me: error: invalid value of canonical build" >&2;} + { (exit 1); exit 1; }; };; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6; } +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} + { (exit 1); exit 1; }; } +fi + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 +echo "$as_me: error: invalid value of canonical host" >&2;} + { (exit 1); exit 1; }; };; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +{ echo "$as_me:$LINENO: checking target system type" >&5 +echo $ECHO_N "checking target system type... $ECHO_C" >&6; } +if test "${ac_cv_target+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "x$target_alias" = x; then + ac_cv_target=$ac_cv_host +else + ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&2;} + { (exit 1); exit 1; }; } +fi + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_target" >&5 +echo "${ECHO_T}$ac_cv_target" >&6; } +case $ac_cv_target in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical target" >&5 +echo "$as_me: error: invalid value of canonical target" >&2;} + { (exit 1); exit 1; }; };; +esac +target=$ac_cv_target +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_target +shift +target_cpu=$1 +target_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +target_os=$* +IFS=$ac_save_IFS +case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac + + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +test -n "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- +case x"$target_cpu" in +"xx86_64") + +cat >>confdefs.h <<\_ACEOF +#define STRESSAPPTEST_CPU_X86_64 +_ACEOF + +;; +"xi686") + +cat >>confdefs.h <<\_ACEOF +#define STRESSAPPTEST_CPU_I686 +_ACEOF + +;; +"xpowerpc") + +cat >>confdefs.h <<\_ACEOF +#define STRESSAPPTEST_CPU_PPC +_ACEOF + +;; +esac + +am__api_version='1.10' + +# 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 +# AmigaOS /C/install, which installs bootblocks on floppy discs +# 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" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /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 + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done +IFS=$as_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. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&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}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ echo "$as_me:$LINENO: checking whether build environment is sane" >&5 +echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&5 +echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&2;} + { (exit 1); exit 1; }; } + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! +Check your system clock" >&5 +echo "$as_me: error: newly created file is older than distributed files! +Check your system clock" >&2;} + { (exit 1); exit 1; }; } +fi +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. echo might interpret backslashes. +# By default was `s,x,x', remove it if useless. +cat <<\_ACEOF >conftest.sed +s/[\\$]/&&/g;s/;s,x,x,$// +_ACEOF +program_transform_name=`echo $program_transform_name | sed -f conftest.sed` +rm -f conftest.sed + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 +echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +{ echo "$as_me:$LINENO: checking for a thread-safe mkdir -p" >&5 +echo $ECHO_N "checking for a thread-safe mkdir -p... $ECHO_C" >&6; } +if test -z "$MKDIR_P"; then + if test "${ac_cv_path_mkdir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done +done +IFS=$as_save_IFS + +fi + + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + test -d ./--version && rmdir ./--version + MKDIR_P="$ac_install_sh -d" + fi +fi +{ echo "$as_me:$LINENO: result: $MKDIR_P" >&5 +echo "${ECHO_T}$MKDIR_P" >&6; } + +mkdir_p="$MKDIR_P" +case $mkdir_p in + [\\/$]* | ?:[\\/]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_AWK+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { echo "$as_me:$LINENO: result: $AWK" >&5 +echo "${ECHO_T}$AWK" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; } +set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + SET_MAKE= +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 +echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} + { (exit 1); exit 1; }; } + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='stressapptest' + VERSION='1.0.0_autoconf' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"} + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +echo "${ECHO_T}$ac_ct_STRIP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. + +AMTAR=${AMTAR-"${am_missing_run}tar"} + +am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' + + + + + + +ac_config_headers="$ac_config_headers src/stressapptest_config.h" + + +# Checks for programs. +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { echo "$as_me:$LINENO: result: $CXX" >&5 +echo "${ECHO_T}$CXX" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 +echo "${ECHO_T}$ac_ct_CXX" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C++ compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ echo "$as_me:$LINENO: checking for C++ compiler default output file name" >&5 +echo $ECHO_N "checking for C++ compiler default output file name... $ECHO_C" >&6; } +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +# +# List of possible output files, starting from the most likely. +# The algorithm is not robust to junk in `.', hence go to wildcards (a.*) +# only as a last resort. b.out is created by i960 compilers. +ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' +# +# The IRIX 6 linker writes into existing files which may not be +# executable, retaining their permissions. Remove them first so a +# subsequent execution test works. +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { (ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi + +{ echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6; } +if test -z "$ac_file"; then + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C++ compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C++ compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext + +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether the C++ compiler works" >&5 +echo $ECHO_N "checking whether the C++ compiler works... $ECHO_C" >&6; } +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C++ compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C++ compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6; } + +{ echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +{ echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6; } +if test "${ac_cv_cxx_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6; } +GXX=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 +echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cxx_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cxx_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CXXFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cxx_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 +echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi + + +{ echo "$as_me:$LINENO: result: $_am_result" >&5 +echo "${ECHO_T}$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +depcc="$CXX" am_compiler_list= + +{ echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; } +if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5 +echo "${ECHO_T}$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + fi +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 "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_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 $# != 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 + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&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 +{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_c89=$ac_arg +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6; } ;; + xno) + { echo "$as_me:$LINENO: result: unsupported" >&5 +echo "${ECHO_T}unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; +esac + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CC" am_compiler_list= + +{ echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; } +if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 +echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + +#Getting user and host info +username=$(whoami) +{ echo "$as_me:$LINENO: checking user ID" >&5 +echo $ECHO_N "checking user ID... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: $username" >&5 +echo "${ECHO_T}$username" >&6; } + +hostname=$(uname -n) +{ echo "$as_me:$LINENO: checking host name" >&5 +echo $ECHO_N "checking host name... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: $hostname" >&5 +echo "${ECHO_T}$hostname" >&6; } + +timestamp=$(date) +{ echo "$as_me:$LINENO: checking current timestamp" >&5 +echo $ECHO_N "checking current timestamp... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: $timestamp" >&5 +echo "${ECHO_T}$timestamp" >&6; } + + +cat >>confdefs.h <<_ACEOF +#define STRESSAPPTEST_TIMESTAMP "$username @ $hostname on $timestamp" +_ACEOF + + +#Default cxxflags +CXXFLAGS="$CXXFLAGS -DCHECKOPTS" +CXXFLAGS="$CXXFLAGS -Wreturn-type -Wunused -Wuninitialized -Wall" +CXXFLAGS="$CXXFLAGS -O3 -funroll-all-loops -funroll-loops -DNDEBUG" + +# Checks for header files. + + + + + + +ac_header_dirent=no +for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do + as_ac_Header=`echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_hdr that defines DIR" >&5 +echo $ECHO_N "checking for $ac_hdr that defines DIR... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include <$ac_hdr> + +int +main () +{ +if ((DIR *) 0) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 +_ACEOF + +ac_header_dirent=$ac_hdr; break +fi + +done +# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. +if test $ac_header_dirent = dirent.h; then + { echo "$as_me:$LINENO: checking for library containing opendir" >&5 +echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6; } +if test "${ac_cv_search_opendir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_func_search_save_LIBS=$LIBS +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char opendir (); +int +main () +{ +return opendir (); + ; + return 0; +} +_ACEOF +for ac_lib in '' dir; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_search_opendir=$ac_res +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext + if test "${ac_cv_search_opendir+set}" = set; then + break +fi +done +if test "${ac_cv_search_opendir+set}" = set; then + : +else + ac_cv_search_opendir=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 +echo "${ECHO_T}$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +else + { echo "$as_me:$LINENO: checking for library containing opendir" >&5 +echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6; } +if test "${ac_cv_search_opendir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_func_search_save_LIBS=$LIBS +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char opendir (); +int +main () +{ +return opendir (); + ; + return 0; +} +_ACEOF +for ac_lib in '' x; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_search_opendir=$ac_res +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext + if test "${ac_cv_search_opendir+set}" = set; then + break +fi +done +if test "${ac_cv_search_opendir+set}" = set; then + : +else + ac_cv_search_opendir=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 +echo "${ECHO_T}$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 +echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Extract the first word of "grep ggrep" to use in msg output +if test -z "$GREP"; then +set dummy grep ggrep; ac_prog_name=$2 +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_GREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue + # Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_GREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +GREP="$ac_cv_path_GREP" +if test -z "$GREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_GREP=$GREP +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 +echo "${ECHO_T}$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + # Extract the first word of "egrep" to use in msg output +if test -z "$EGREP"; then +set dummy egrep; ac_prog_name=$2 +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_EGREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue + # Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_EGREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +EGREP="$ac_cv_path_EGREP" +if test -z "$EGREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_EGREP=$EGREP +fi + + + fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 +echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_stdc=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + 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 <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + 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 <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#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)) + return 2; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + + + + + + + + + + +for ac_header in arpa/inet.h fcntl.h malloc.h netdb.h stdint.h stdlib.h string.h sys/ioctl.h sys/socket.h sys/time.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ----------------------------------- ## +## Report this to opensource@gmail.com ## +## ----------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +# Checks for typedefs, structures, and compiler characteristics. +{ echo "$as_me:$LINENO: checking for stdbool.h that conforms to C99" >&5 +echo $ECHO_N "checking for stdbool.h that conforms to C99... $ECHO_C" >&6; } +if test "${ac_cv_header_stdbool_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#ifndef bool + "error: bool is not defined" +#endif +#ifndef false + "error: false is not defined" +#endif +#if false + "error: false is not 0" +#endif +#ifndef true + "error: true is not defined" +#endif +#if true != 1 + "error: true is not 1" +#endif +#ifndef __bool_true_false_are_defined + "error: __bool_true_false_are_defined is not defined" +#endif + + struct s { _Bool s: 1; _Bool t; } s; + + char a[true == 1 ? 1 : -1]; + char b[false == 0 ? 1 : -1]; + char c[__bool_true_false_are_defined == 1 ? 1 : -1]; + char d[(bool) 0.5 == true ? 1 : -1]; + bool e = &s; + char f[(_Bool) 0.0 == false ? 1 : -1]; + char g[true]; + char h[sizeof (_Bool)]; + char i[sizeof s.t]; + enum { j = false, k = true, l = false * true, m = true * 256 }; + _Bool n[m]; + char o[sizeof n == m * sizeof n[0] ? 1 : -1]; + char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1]; +# if defined __xlc__ || defined __GNUC__ + /* Catch a bug in IBM AIX xlc compiler version 6.0.0.0 + reported by James Lemley on 2005-10-05; see + http://lists.gnu.org/archive/html/bug-coreutils/2005-10/msg00086.html + This test is not quite right, since xlc is allowed to + reject this program, as the initializer for xlcbug is + not one of the forms that C requires support for. + However, doing the test right would require a runtime + test, and that would make cross-compilation harder. + Let us hope that IBM fixes the xlc bug, and also adds + support for this kind of constant expression. In the + meantime, this test will reject xlc, which is OK, since + our stdbool.h substitute should suffice. We also test + this with GCC, where it should work, to detect more + quickly whether someone messes up the test in the + future. */ + char digs[] = "0123456789"; + int xlcbug = 1 / (&(digs + 5)[-2 + (bool) 1] == &digs[4] ? 1 : -1); +# endif + /* Catch a bug in an HP-UX C compiler. See + http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html + http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html + */ + _Bool q = true; + _Bool *pq = &q; + +int +main () +{ + + *pq |= q; + *pq |= ! q; + /* Refer to every declared value, to avoid compiler optimizations. */ + return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l + + !m + !n + !o + !p + !q + !pq); + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_stdbool_h=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_stdbool_h=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_stdbool_h" >&5 +echo "${ECHO_T}$ac_cv_header_stdbool_h" >&6; } +{ echo "$as_me:$LINENO: checking for _Bool" >&5 +echo $ECHO_N "checking for _Bool... $ECHO_C" >&6; } +if test "${ac_cv_type__Bool+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef _Bool ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type__Bool=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type__Bool=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type__Bool" >&5 +echo "${ECHO_T}$ac_cv_type__Bool" >&6; } +if test $ac_cv_type__Bool = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE__BOOL 1 +_ACEOF + + +fi + +if test $ac_cv_header_stdbool_h = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_STDBOOL_H 1 +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 +echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6; } +if test "${ac_cv_c_const+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset cs; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_const=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_c_const=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 +echo "${ECHO_T}$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +cat >>confdefs.h <<\_ACEOF +#define const +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking for inline" >&5 +echo $ECHO_N "checking for inline... $ECHO_C" >&6; } +if test "${ac_cv_c_inline+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_inline=$ac_kw +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 +echo "${ECHO_T}$ac_cv_c_inline" >&6; } + + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + +{ echo "$as_me:$LINENO: checking for pid_t" >&5 +echo $ECHO_N "checking for pid_t... $ECHO_C" >&6; } +if test "${ac_cv_type_pid_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef pid_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_pid_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_pid_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5 +echo "${ECHO_T}$ac_cv_type_pid_t" >&6; } +if test $ac_cv_type_pid_t = yes; then + : +else + +cat >>confdefs.h <<_ACEOF +#define pid_t int +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking for C/C++ restrict keyword" >&5 +echo $ECHO_N "checking for C/C++ restrict keyword... $ECHO_C" >&6; } +if test "${ac_cv_c_restrict+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_c_restrict=no + # Try the official restrict keyword, then gcc's __restrict, and + # the less common variants. + for ac_kw in restrict __restrict __restrict__ _Restrict; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +typedef int * int_ptr; + int foo (int_ptr $ac_kw ip) { + return ip[0]; + } +int +main () +{ +int s[1]; + int * $ac_kw t = s; + t[0] = 0; + return foo(t) + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_restrict=$ac_kw +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_restrict" != no && break + done + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_restrict" >&5 +echo "${ECHO_T}$ac_cv_c_restrict" >&6; } + case $ac_cv_c_restrict in + restrict) ;; + no) +cat >>confdefs.h <<\_ACEOF +#define restrict +_ACEOF + ;; + *) cat >>confdefs.h <<_ACEOF +#define restrict $ac_cv_c_restrict +_ACEOF + ;; + esac + +{ echo "$as_me:$LINENO: checking for ssize_t" >&5 +echo $ECHO_N "checking for ssize_t... $ECHO_C" >&6; } +if test "${ac_cv_type_ssize_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef ssize_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_ssize_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_ssize_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_ssize_t" >&5 +echo "${ECHO_T}$ac_cv_type_ssize_t" >&6; } +if test $ac_cv_type_ssize_t = yes; then + : +else + +cat >>confdefs.h <<_ACEOF +#define ssize_t int +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 +echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6; } +if test "${ac_cv_header_time+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_time=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_time=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 +echo "${ECHO_T}$ac_cv_header_time" >&6; } +if test $ac_cv_header_time = yes; then + +cat >>confdefs.h <<\_ACEOF +#define TIME_WITH_SYS_TIME 1 +_ACEOF + +fi + + + { echo "$as_me:$LINENO: checking for uint16_t" >&5 +echo $ECHO_N "checking for uint16_t... $ECHO_C" >&6; } +if test "${ac_cv_c_uint16_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_c_uint16_t=no + for ac_type in 'uint16_t' 'unsigned int' 'unsigned long int' \ + 'unsigned long long int' 'unsigned short int' 'unsigned char'; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(($ac_type) -1 >> (16 - 1) == 1)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + case $ac_type in + uint16_t) ac_cv_c_uint16_t=yes ;; + *) ac_cv_c_uint16_t=$ac_type ;; +esac + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_uint16_t" != no && break + done +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_uint16_t" >&5 +echo "${ECHO_T}$ac_cv_c_uint16_t" >&6; } + case $ac_cv_c_uint16_t in #( + no|yes) ;; #( + *) + + +cat >>confdefs.h <<_ACEOF +#define uint16_t $ac_cv_c_uint16_t +_ACEOF +;; + esac + +{ echo "$as_me:$LINENO: checking for working volatile" >&5 +echo $ECHO_N "checking for working volatile... $ECHO_C" >&6; } +if test "${ac_cv_c_volatile+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + +volatile int x; +int * volatile y = (int *) 0; +return !x && !y; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_volatile=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_c_volatile=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_volatile" >&5 +echo "${ECHO_T}$ac_cv_c_volatile" >&6; } +if test $ac_cv_c_volatile = no; then + +cat >>confdefs.h <<\_ACEOF +#define volatile +_ACEOF + +fi + + +# Checking for pthreads +pthread_arg="not_available" +{ echo "$as_me:$LINENO: checking which argument is required to compile pthreads" >&5 +echo $ECHO_N "checking which argument is required to compile pthreads... $ECHO_C" >&6; } + +pthread_header="#include" +pthread_body="pthread_create(0,0,0,0)" +# Check if compile with no extra argument +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$pthread_header +int +main () +{ +$pthread_body + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + pthread_arg="" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + +if test x"$pthread_arg" = x"not_available"; then + # At first, only -pthread was tested, but this is the place + # to add extra pthread flags if someone can test them + bkp_LDFLAGS="$LDFLAGS" + for altheader in -pthread; do + LDFLAGS="$bkp_LDFLAGS $altheader" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$pthread_header +int +main () +{ +$pthread_body + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + pthread_arg="$altheader" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$bkp_LDFLAGS" + done +fi + +if test x"$pthread_arg" = x"not_available"; then + { { echo "$as_me:$LINENO: error: Cannot find a proper pthread library +See \`config.log' for more details." >&5 +echo "$as_me: error: Cannot find a proper pthread library +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +else + if test x"$pthread_arg" = x; then + { echo "$as_me:$LINENO: result: none" >&5 +echo "${ECHO_T}none" >&6; } + else + { echo "$as_me:$LINENO: result: $pthread_arg" >&5 +echo "${ECHO_T}$pthread_arg" >&6; } + fi + LDFLAGS="$LDFLAGS $pthread_arg" +fi + +# Checks for library functions. +{ echo "$as_me:$LINENO: checking whether closedir returns void" >&5 +echo $ECHO_N "checking whether closedir returns void... $ECHO_C" >&6; } +if test "${ac_cv_func_closedir_void+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_closedir_void=yes +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header_dirent> +#ifndef __cplusplus +int closedir (); +#endif + +int +main () +{ +return closedir (opendir (".")) != 0; + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_closedir_void=no +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_func_closedir_void=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_closedir_void" >&5 +echo "${ECHO_T}$ac_cv_func_closedir_void" >&6; } +if test $ac_cv_func_closedir_void = yes; then + +cat >>confdefs.h <<\_ACEOF +#define CLOSEDIR_VOID 1 +_ACEOF + +fi + +if test $ac_cv_c_compiler_gnu = yes; then + { echo "$as_me:$LINENO: checking whether $CC needs -traditional" >&5 +echo $ECHO_N "checking whether $CC needs -traditional... $ECHO_C" >&6; } +if test "${ac_cv_prog_gcc_traditional+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_pattern="Autoconf.*'x'" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +Autoconf TIOCGETP +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "$ac_pattern" >/dev/null 2>&1; then + ac_cv_prog_gcc_traditional=yes +else + ac_cv_prog_gcc_traditional=no +fi +rm -f conftest* + + + if test $ac_cv_prog_gcc_traditional = no; then + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +Autoconf TCGETA +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "$ac_pattern" >/dev/null 2>&1; then + ac_cv_prog_gcc_traditional=yes +fi +rm -f conftest* + + fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_gcc_traditional" >&5 +echo "${ECHO_T}$ac_cv_prog_gcc_traditional" >&6; } + if test $ac_cv_prog_gcc_traditional = yes; then + CC="$CC -traditional" + fi +fi + + + +for ac_header in sys/select.h sys/socket.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ----------------------------------- ## +## Report this to opensource@gmail.com ## +## ----------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +{ echo "$as_me:$LINENO: checking types of arguments for select" >&5 +echo $ECHO_N "checking types of arguments for select... $ECHO_C" >&6; } +if test "${ac_cv_func_select_args+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + for ac_arg234 in 'fd_set *' 'int *' 'void *'; do + for ac_arg1 in 'int' 'size_t' 'unsigned long int' 'unsigned int'; do + for ac_arg5 in 'struct timeval *' 'const struct timeval *'; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#ifdef HAVE_SYS_SELECT_H +# include +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif + +int +main () +{ +extern int select ($ac_arg1, + $ac_arg234, $ac_arg234, $ac_arg234, + $ac_arg5); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_func_select_args="$ac_arg1,$ac_arg234,$ac_arg5"; break 3 +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done + done +done +# Provide a safe default value. +: ${ac_cv_func_select_args='int,int *,struct timeval *'} + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_select_args" >&5 +echo "${ECHO_T}$ac_cv_func_select_args" >&6; } +ac_save_IFS=$IFS; IFS=',' +set dummy `echo "$ac_cv_func_select_args" | sed 's/\*/\*/g'` +IFS=$ac_save_IFS +shift + +cat >>confdefs.h <<_ACEOF +#define SELECT_TYPE_ARG1 $1 +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define SELECT_TYPE_ARG234 ($2) +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define SELECT_TYPE_ARG5 ($3) +_ACEOF + +rm -f conftest* + +{ echo "$as_me:$LINENO: checking return type of signal handlers" >&5 +echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6; } +if test "${ac_cv_type_signal+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include + +int +main () +{ +return *(signal (0, 0)) (0) == 1; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_signal=int +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_signal=void +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5 +echo "${ECHO_T}$ac_cv_type_signal" >&6; } + +cat >>confdefs.h <<_ACEOF +#define RETSIGTYPE $ac_cv_type_signal +_ACEOF + + +{ echo "$as_me:$LINENO: checking whether strerror_r is declared" >&5 +echo $ECHO_N "checking whether strerror_r is declared... $ECHO_C" >&6; } +if test "${ac_cv_have_decl_strerror_r+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +#ifndef strerror_r + (void) strerror_r; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_have_decl_strerror_r=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_have_decl_strerror_r=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_have_decl_strerror_r" >&5 +echo "${ECHO_T}$ac_cv_have_decl_strerror_r" >&6; } +if test $ac_cv_have_decl_strerror_r = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_STRERROR_R 1 +_ACEOF + + +else + cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_STRERROR_R 0 +_ACEOF + + +fi + + + +for ac_func in strerror_r +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* 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 +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +{ echo "$as_me:$LINENO: checking whether strerror_r returns char *" >&5 +echo $ECHO_N "checking whether strerror_r returns char *... $ECHO_C" >&6; } +if test "${ac_cv_func_strerror_r_char_p+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + ac_cv_func_strerror_r_char_p=no + if test $ac_cv_have_decl_strerror_r = yes; then + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + char buf[100]; + char x = *strerror_r (0, buf, sizeof buf); + char *p = strerror_r (0, buf, sizeof buf); + return !p || x; + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_func_strerror_r_char_p=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + else + # strerror_r is not declared. Choose between + # systems that have relatively inaccessible declarations for the + # function. BeOS and DEC UNIX 4.0 fall in this category, but the + # former has a strerror_r that returns char*, while the latter + # has a strerror_r that returns `int'. + # This test should segfault on the DEC system. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + extern char *strerror_r (); +int +main () +{ +char buf[100]; + char x = *strerror_r (0, buf, sizeof buf); + return ! isalpha (x); + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_strerror_r_char_p=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + + fi + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_strerror_r_char_p" >&5 +echo "${ECHO_T}$ac_cv_func_strerror_r_char_p" >&6; } +if test $ac_cv_func_strerror_r_char_p = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STRERROR_R_CHAR_P 1 +_ACEOF + +fi + + +for ac_func in vprintf +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* 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 +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +{ echo "$as_me:$LINENO: checking for _doprnt" >&5 +echo $ECHO_N "checking for _doprnt... $ECHO_C" >&6; } +if test "${ac_cv_func__doprnt+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define _doprnt to an innocuous variant, in case declares _doprnt. + For example, HP-UX 11i declares gettimeofday. */ +#define _doprnt innocuous__doprnt + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char _doprnt (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef _doprnt + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char _doprnt (); +/* 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 +#endif + +int +main () +{ +return _doprnt (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_func__doprnt=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func__doprnt=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func__doprnt" >&5 +echo "${ECHO_T}$ac_cv_func__doprnt" >&6; } +if test $ac_cv_func__doprnt = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_DOPRNT 1 +_ACEOF + +fi + +fi +done + + + + + + + + +for ac_func in gettimeofday memset select socket strtol strtoull +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* 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 +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +ac_config_files="$ac_config_files Makefile src/Makefile" + +cat >confcache <<\_ACEOF +# 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, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# 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. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { echo "$as_me:$LINENO: updating cache $cache_file" >&5 +echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 +echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 + +# Save the log message, to keep $[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by stressapptest $as_me 1.0.0_autoconf, which was +generated by GNU Autoconf 2.61. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +stressapptest config.status 1.0.0_autoconf +configured by $0, generated by GNU Autoconf 2.61, + with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2006 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + { echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + CONFIG_SHELL=$SHELL + export CONFIG_SHELL + exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "src/stressapptest_config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/stressapptest_config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +# +# Set up the sed scripts for CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "$CONFIG_FILES"; then + +_ACEOF + + + +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + cat >conf$$subs.sed <<_ACEOF +SHELL!$SHELL$ac_delim +PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim +PACKAGE_NAME!$PACKAGE_NAME$ac_delim +PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim +PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim +PACKAGE_STRING!$PACKAGE_STRING$ac_delim +PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim +exec_prefix!$exec_prefix$ac_delim +prefix!$prefix$ac_delim +program_transform_name!$program_transform_name$ac_delim +bindir!$bindir$ac_delim +sbindir!$sbindir$ac_delim +libexecdir!$libexecdir$ac_delim +datarootdir!$datarootdir$ac_delim +datadir!$datadir$ac_delim +sysconfdir!$sysconfdir$ac_delim +sharedstatedir!$sharedstatedir$ac_delim +localstatedir!$localstatedir$ac_delim +includedir!$includedir$ac_delim +oldincludedir!$oldincludedir$ac_delim +docdir!$docdir$ac_delim +infodir!$infodir$ac_delim +htmldir!$htmldir$ac_delim +dvidir!$dvidir$ac_delim +pdfdir!$pdfdir$ac_delim +psdir!$psdir$ac_delim +libdir!$libdir$ac_delim +localedir!$localedir$ac_delim +mandir!$mandir$ac_delim +DEFS!$DEFS$ac_delim +ECHO_C!$ECHO_C$ac_delim +ECHO_N!$ECHO_N$ac_delim +ECHO_T!$ECHO_T$ac_delim +LIBS!$LIBS$ac_delim +build_alias!$build_alias$ac_delim +host_alias!$host_alias$ac_delim +target_alias!$target_alias$ac_delim +build!$build$ac_delim +build_cpu!$build_cpu$ac_delim +build_vendor!$build_vendor$ac_delim +build_os!$build_os$ac_delim +host!$host$ac_delim +host_cpu!$host_cpu$ac_delim +host_vendor!$host_vendor$ac_delim +host_os!$host_os$ac_delim +target!$target$ac_delim +target_cpu!$target_cpu$ac_delim +target_vendor!$target_vendor$ac_delim +target_os!$target_os$ac_delim +INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim +INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim +INSTALL_DATA!$INSTALL_DATA$ac_delim +am__isrc!$am__isrc$ac_delim +CYGPATH_W!$CYGPATH_W$ac_delim +PACKAGE!$PACKAGE$ac_delim +VERSION!$VERSION$ac_delim +ACLOCAL!$ACLOCAL$ac_delim +AUTOCONF!$AUTOCONF$ac_delim +AUTOMAKE!$AUTOMAKE$ac_delim +AUTOHEADER!$AUTOHEADER$ac_delim +MAKEINFO!$MAKEINFO$ac_delim +install_sh!$install_sh$ac_delim +STRIP!$STRIP$ac_delim +INSTALL_STRIP_PROGRAM!$INSTALL_STRIP_PROGRAM$ac_delim +mkdir_p!$mkdir_p$ac_delim +AWK!$AWK$ac_delim +SET_MAKE!$SET_MAKE$ac_delim +am__leading_dot!$am__leading_dot$ac_delim +AMTAR!$AMTAR$ac_delim +am__tar!$am__tar$ac_delim +am__untar!$am__untar$ac_delim +CXX!$CXX$ac_delim +CXXFLAGS!$CXXFLAGS$ac_delim +LDFLAGS!$LDFLAGS$ac_delim +CPPFLAGS!$CPPFLAGS$ac_delim +ac_ct_CXX!$ac_ct_CXX$ac_delim +EXEEXT!$EXEEXT$ac_delim +OBJEXT!$OBJEXT$ac_delim +DEPDIR!$DEPDIR$ac_delim +am__include!$am__include$ac_delim +am__quote!$am__quote$ac_delim +AMDEP_TRUE!$AMDEP_TRUE$ac_delim +AMDEP_FALSE!$AMDEP_FALSE$ac_delim +AMDEPBACKSLASH!$AMDEPBACKSLASH$ac_delim +CXXDEPMODE!$CXXDEPMODE$ac_delim +am__fastdepCXX_TRUE!$am__fastdepCXX_TRUE$ac_delim +am__fastdepCXX_FALSE!$am__fastdepCXX_FALSE$ac_delim +CC!$CC$ac_delim +CFLAGS!$CFLAGS$ac_delim +ac_ct_CC!$ac_ct_CC$ac_delim +CCDEPMODE!$CCDEPMODE$ac_delim +am__fastdepCC_TRUE!$am__fastdepCC_TRUE$ac_delim +am__fastdepCC_FALSE!$am__fastdepCC_FALSE$ac_delim +CPP!$CPP$ac_delim +GREP!$GREP$ac_delim +EGREP!$EGREP$ac_delim +LIBOBJS!$LIBOBJS$ac_delim +_ACEOF + + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +if test -n "$ac_eof"; then + ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` + ac_eof=`expr $ac_eof + 1` +fi + +cat >>$CONFIG_STATUS <<_ACEOF +cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +_ACEOF +sed ' +s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +s/^/s,@/; s/!/@,|#_!!_#|/ +:n +t n +s/'"$ac_delim"'$/,g/; t +s/$/\\/; p +N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF +CEOF$ac_eof +_ACEOF + + +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + cat >conf$$subs.sed <<_ACEOF +LTLIBOBJS!$LTLIBOBJS$ac_delim +_ACEOF + + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 1; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +if test -n "$ac_eof"; then + ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` + ac_eof=`expr $ac_eof + 1` +fi + +cat >>$CONFIG_STATUS <<_ACEOF +cat >"\$tmp/subs-2.sed" <<\CEOF$ac_eof +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end +_ACEOF +sed ' +s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +s/^/s,@/; s/!/@,|#_!!_#|/ +:n +t n +s/'"$ac_delim"'$/,g/; t +s/$/\\/; p +N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF +:end +s/|#_!!_#|//g +CEOF$ac_eof +_ACEOF + + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF +fi # test -n "$CONFIG_FILES" + + +for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 +echo "$as_me: error: Invalid tag $ac_tag." >&2;} + { (exit 1); exit 1; }; };; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + esac + ac_file_inputs="$ac_file_inputs $ac_f" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input="Generated from "`IFS=: + echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + fi + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin";; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir="$ac_dir" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= + +case `sed -n '/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p +' $ac_file_inputs` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s&@configure_input@&$configure_input&;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" >$tmp/out + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out"; rm -f "$tmp/out";; + *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; + esac + ;; + :H) + # + # CONFIG_HEADER + # +_ACEOF + +# Transform confdefs.h into a sed script `conftest.defines', that +# substitutes the proper values into config.h.in to produce config.h. +rm -f conftest.defines conftest.tail +# First, append a space to every undef/define line, to ease matching. +echo 's/$/ /' >conftest.defines +# Then, protect against being on the right side of a sed subst, or in +# an unquoted here document, in config.status. If some macros were +# called several times there might be several #defines for the same +# symbol, which is useless. But do not sort them, since the last +# AC_DEFINE must be honored. +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where +# NAME is the cpp macro being defined, VALUE is the value it is being given. +# PARAMS is the parameter list in the macro definition--in most cases, it's +# just an empty string. +ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*' +ac_dB='\\)[ (].*,\\1define\\2' +ac_dC=' ' +ac_dD=' ,' + +uniq confdefs.h | + sed -n ' + t rset + :rset + s/^[ ]*#[ ]*define[ ][ ]*// + t ok + d + :ok + s/[\\&,]/\\&/g + s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p + s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p + ' >>conftest.defines + +# Remove the space that was appended to ease matching. +# Then replace #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. +# (The regexp can be short, since the line contains either #define or #undef.) +echo 's/ $// +s,^[ #]*u.*,/* & */,' >>conftest.defines + +# Break up conftest.defines: +ac_max_sed_lines=50 + +# First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1" +# Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2" +# Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1" +# et cetera. +ac_in='$ac_file_inputs' +ac_out='"$tmp/out1"' +ac_nxt='"$tmp/out2"' + +while : +do + # Write a here document: + cat >>$CONFIG_STATUS <<_ACEOF + # First, check the format of the line: + cat >"\$tmp/defines.sed" <<\\CEOF +/^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def +/^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def +b +:def +_ACEOF + sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS + ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in + sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail + grep . conftest.tail >/dev/null || break + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines conftest.tail + +echo "ac_result=$ac_in" >>$CONFIG_STATUS +cat >>$CONFIG_STATUS <<\_ACEOF + if test x"$ac_file" != x-; then + echo "/* $configure_input */" >"$tmp/config.h" + cat "$ac_result" >>"$tmp/config.h" + if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f $ac_file + mv "$tmp/config.h" $ac_file + fi + else + echo "/* $configure_input */" + cat "$ac_result" + fi + rm -f "$tmp/out12" +# Compute $ac_file's index in $config_headers. +_am_arg=$ac_file +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { echo "$as_me:$LINENO: executing $ac_file commands" >&5 +echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir=$dirpart/$fdir + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done + ;; + + esac +done # for ac_tag + + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..026fa07 --- /dev/null +++ b/configure.ac @@ -0,0 +1,111 @@ +AC_PREREQ(2.61) +AC_INIT(stressapptest, 1.0.0_autoconf, opensource@gmail.com) + +# Checking for target cpu and setting custom configuration +# for the different platforms +AC_CANONICAL_TARGET +case x"$target_cpu" in +"xx86_64") + AC_DEFINE([STRESSAPPTEST_CPU_X86_64],[], + [Defined if the target CPU is x86_64]) +;; +"xi686") + AC_DEFINE([STRESSAPPTEST_CPU_I686],[], + [Defined if the target CPU is i686]) +;; +"xpowerpc") + AC_DEFINE([STRESSAPPTEST_CPU_PPC],[], + [Defined if the target CPU is PowerPC]) +;; +esac + +AM_INIT_AUTOMAKE([-Wall -Werror foreign]) +AC_CONFIG_SRCDIR([src/]) +AC_CONFIG_HEADER([src/stressapptest_config.h]) + +# Checks for programs. +AC_PROG_CXX +AC_PROG_CC + +#Getting user and host info +username=$(whoami) +AC_MSG_CHECKING([user ID]) +AC_MSG_RESULT([$username]) + +hostname=$(uname -n) +AC_MSG_CHECKING([host name]) +AC_MSG_RESULT([$hostname]) + +timestamp=$(date) +AC_MSG_CHECKING([current timestamp]) +AC_MSG_RESULT([$timestamp]) + +AC_DEFINE_UNQUOTED([STRESSAPPTEST_TIMESTAMP], + "$username @ $hostname on $timestamp", + [Timestamp when ./configure was executed]) + +#Default cxxflags +CXXFLAGS="$CXXFLAGS -DCHECKOPTS" +CXXFLAGS="$CXXFLAGS -Wreturn-type -Wunused -Wuninitialized -Wall" +CXXFLAGS="$CXXFLAGS -O3 -funroll-all-loops -funroll-loops -DNDEBUG" + +# Checks for header files. +AC_HEADER_DIRENT +AC_HEADER_STDC +AC_CHECK_HEADERS([arpa/inet.h fcntl.h malloc.h netdb.h stdint.h stdlib.h string.h sys/ioctl.h sys/socket.h sys/time.h unistd.h]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_HEADER_STDBOOL +AC_C_CONST +AC_C_INLINE +AC_TYPE_PID_T +AC_C_RESTRICT +AC_TYPE_SSIZE_T +AC_HEADER_TIME +AC_TYPE_UINT16_T +AC_C_VOLATILE + +# Checking for pthreads +pthread_arg="not_available" +AC_MSG_CHECKING([which argument is required to compile pthreads]) + +pthread_header="#include" +pthread_body="pthread_create(0,0,0,0)" +# Check if compile with no extra argument +AC_LINK_IFELSE([AC_LANG_PROGRAM($pthread_header, $pthread_body)], +pthread_arg="") + +if test x"$pthread_arg" = x"not_available"; then + # At first, only -pthread was tested, but this is the place + # to add extra pthread flags if someone can test them + bkp_LDFLAGS="$LDFLAGS" + for altheader in -pthread; do + LDFLAGS="$bkp_LDFLAGS $altheader" + AC_LINK_IFELSE([AC_LANG_PROGRAM($pthread_header, $pthread_body)], + pthread_arg="$altheader") + LDFLAGS="$bkp_LDFLAGS" + done +fi + +if test x"$pthread_arg" = x"not_available"; then + AC_MSG_FAILURE([Cannot find a proper pthread library]) +else + if test x"$pthread_arg" = x; then + AC_MSG_RESULT([none]) + else + AC_MSG_RESULT([$pthread_arg]) + fi + LDFLAGS="$LDFLAGS $pthread_arg" +fi + +# Checks for library functions. +AC_FUNC_CLOSEDIR_VOID +AC_PROG_GCC_TRADITIONAL +AC_FUNC_SELECT_ARGTYPES +AC_TYPE_SIGNAL +AC_FUNC_STRERROR_R +AC_FUNC_VPRINTF +AC_CHECK_FUNCS([gettimeofday memset select socket strtol strtoull]) + +AC_CONFIG_FILES([Makefile src/Makefile]) +AC_OUTPUT diff --git a/depcomp b/depcomp new file mode 100755 index 0000000..e5f9736 --- /dev/null +++ b/depcomp @@ -0,0 +1,589 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2007-03-29.01 + +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007 Free Software +# Foundation, Inc. + +# 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, 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. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputing dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> $depfile + echo >> $depfile + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> $depfile + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts `$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" + # Add `dependent.h:' lines. + sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mechanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no + for arg in "$@"; do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix="`echo $object | sed 's/^.*\././'`" + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + "$@" || exit $? + IFS=" " + for arg + do + case "$arg" in + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/install-sh b/install-sh new file mode 100755 index 0000000..a5897de --- /dev/null +++ b/install-sh @@ -0,0 +1,519 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2006-12-25.00 + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# 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. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + trap '(exit $?); exit' 1 2 13 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dst_arg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + -*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test -z "$d" && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # 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 $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/missing b/missing new file mode 100755 index 0000000..1c8ff70 --- /dev/null +++ b/missing @@ -0,0 +1,367 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2006-05-10.23 + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006 +# Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, 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. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case $1 in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + autom4te touch the output file, or create a stub one + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). +case $1 in + lex|yacc) + # Not GNU programs, they don't have --version. + ;; + + tar) + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + exit 1 + fi + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case $1 in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case $f in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if test ! -f y.tab.h; then + echo >y.tab.h + fi + if test ! -f y.tab.c; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if test ! -f lex.yy.c; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit 1 + fi + ;; + + makeinfo) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + tar) + shift + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case $firstarg in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case $firstarg in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..e044974 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,31 @@ +bin_PROGRAMS = stressapptest + +AM_DEFAULT_SOURCE_EXT=.cc + +MAINFILES = main.cc +CFILES = os.cc +CFILES += os_factory.cc +CFILES += pattern.cc +CFILES += queue.cc +CFILES += sat.cc +CFILES += sat_factory.cc +CFILES += worker.cc +CFILES += finelock_queue.cc +CFILES += error_diag.cc +CFILES += disk_blocks.cc +CFILES += adler32memcpy.cc +CFILES += logger.cc + +HFILES = os.h +HFILES += pattern.h +HFILES += queue.h +HFILES += sat.h +HFILES += worker.h +HFILES += sattypes.h +HFILES += finelock_queue.h +HFILES += error_diag.h +HFILES += disk_blocks.h +HFILES += adler32memcpy.h +HFILES += logger.h + +stressapptest_SOURCES = $(MAINFILES) $(CFILES) $(HFILES) diff --git a/src/Makefile.in b/src/Makefile.in new file mode 100644 index 0000000..7cd6f2a --- /dev/null +++ b/src/Makefile.in @@ -0,0 +1,476 @@ +# Makefile.in generated by automake 1.10.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +bin_PROGRAMS = stressapptest$(EXEEXT) +subdir = src +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(srcdir)/stressapptest_config.h.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = stressapptest_config.h +CONFIG_CLEAN_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" +binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) +PROGRAMS = $(bin_PROGRAMS) +am__objects_1 = main.$(OBJEXT) +am__objects_2 = os.$(OBJEXT) os_factory.$(OBJEXT) pattern.$(OBJEXT) \ + queue.$(OBJEXT) sat.$(OBJEXT) sat_factory.$(OBJEXT) \ + worker.$(OBJEXT) finelock_queue.$(OBJEXT) error_diag.$(OBJEXT) \ + disk_blocks.$(OBJEXT) adler32memcpy.$(OBJEXT) logger.$(OBJEXT) +am__objects_3 = +am_stressapptest_OBJECTS = $(am__objects_1) $(am__objects_2) \ + $(am__objects_3) +stressapptest_OBJECTS = $(am_stressapptest_OBJECTS) +stressapptest_LDADD = $(LDADD) +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(stressapptest_SOURCES) +DIST_SOURCES = $(stressapptest_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_DEFAULT_SOURCE_EXT = .cc +MAINFILES = main.cc +CFILES = os.cc os_factory.cc pattern.cc queue.cc sat.cc sat_factory.cc \ + worker.cc finelock_queue.cc error_diag.cc disk_blocks.cc \ + adler32memcpy.cc logger.cc +HFILES = os.h pattern.h queue.h sat.h worker.h sattypes.h \ + finelock_queue.h error_diag.h disk_blocks.h adler32memcpy.h \ + logger.h +stressapptest_SOURCES = $(MAINFILES) $(CFILES) $(HFILES) +all: stressapptest_config.h + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .cc .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +stressapptest_config.h: stamp-h1 + @if test ! -f $@; then \ + rm -f stamp-h1; \ + $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ + else :; fi + +stamp-h1: $(srcdir)/stressapptest_config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status src/stressapptest_config.h +$(srcdir)/stressapptest_config.h.in: $(am__configure_deps) + cd $(top_srcdir) && $(AUTOHEADER) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f stressapptest_config.h stamp-h1 +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + ; then \ + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ + rm -f "$(DESTDIR)$(bindir)/$$f"; \ + done + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) +stressapptest$(EXEEXT): $(stressapptest_OBJECTS) $(stressapptest_DEPENDENCIES) + @rm -f stressapptest$(EXEEXT) + $(CXXLINK) $(stressapptest_OBJECTS) $(stressapptest_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/adler32memcpy.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/disk_blocks.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/error_diag.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/finelock_queue.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logger.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/os.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/os_factory.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pattern.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/queue.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sat_factory.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/worker.Po@am__quote@ + +.cc.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cc.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) stressapptest_config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) stressapptest_config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) stressapptest_config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + list='$(SOURCES) $(HEADERS) stressapptest_config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) stressapptest_config.h +installdirs: + for dir in "$(DESTDIR)$(bindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-exec-am: install-binPROGRAMS + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ + clean-generic ctags distclean distclean-compile \ + distclean-generic distclean-hdr distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-binPROGRAMS install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-binPROGRAMS + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/adler32memcpy.cc b/src/adler32memcpy.cc new file mode 100644 index 0000000..529dcc4 --- /dev/null +++ b/src/adler32memcpy.cc @@ -0,0 +1,380 @@ +// Copyright 2008 Google Inc. All Rights Reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "adler32memcpy.h" + +// We are using (a modified form of) adler-32 checksum algorithm instead +// of CRC since adler-32 is faster than CRC. +// (Comparison: http://guru.multimedia.cx/crc32-vs-adler32/) +// This form of adler is bit modified, instead of treating the data in +// units of bytes, 32-bit data is taken as a unit and two 64-bit +// checksums are done (we could have one checksum but two checksums +// make the code run faster). + +// Adler-32 implementation: +// Data is treated as 1-byte numbers and, +// there are two 16-bit numbers a and b +// Initialize a with 1 and b with 0. +// for each data unit 'd' +// a += d +// b += a +// checksum = a<<16 + b +// This sum should never overflow. +// +// Adler-64+64 implementation: +// (applied in this code) +// Data is treated as 32-bit numbers and whole data is separated into two +// streams, and hence the two checksums a1, a2, b1 and b2. +// Initialize a1 and a2 with 1, b1 and b2 with 0 +// add first dataunit to a1 +// add a1 to b1 +// add second dataunit to a1 +// add a1 to b1 +// add third dataunit to a2 +// add a2 to b2 +// add fourth dataunit to a2 +// add a2 to b2 +// ... +// repeat the sequence back for next 4 dataunits +// +// variable A = XMM6 and variable B = XMM7. +// (a1 = lower 8 bytes of XMM6 and b1 = lower 8 bytes of XMM7) + +// Assumptions +// 1. size_in_bytes is a multiple of 16. +// 2. srcmem and dstmem are 16 byte aligned. +// 3. size_in_bytes is less than 2^19 bytes. + +// Assumption 3 ensures that there is no overflow when numbers are being +// added (we can remove this assumption by doing modulus with a prime +// number when it is just about to overflow but that would be a very costly +// exercise) + +// Returns true if the checksums are equal. +bool AdlerChecksum::Equals(const AdlerChecksum &other) const { + return ( (a1_ == other.a1_) && (a2_ == other.a2_) && + (b1_ == other.b1_) && (b2_ == other.b2_) ); +} + +// Returns string representation of the Adler checksum. +string AdlerChecksum::ToHexString() const { + char buffer[128]; + snprintf(buffer, sizeof(buffer), "%llx%llx%llx%llx", a1_, a2_, b1_, b2_); + return string(buffer); +} + +// Sets components of the Adler checksum. +void AdlerChecksum::Set(uint64 a1, uint64 a2, uint64 b1, uint64 b2) { + a1_ = a1; + a2_ = a2; + b1_ = b1; + b2_ = b2; +} + +// Calculates Adler checksum for supplied data. +bool CalculateAdlerChecksum(uint64 *data64, unsigned int size_in_bytes, + AdlerChecksum *checksum) { + // Use this data wrapper to access memory with 64bit read/write. + datacast_t data; + unsigned int count = size_in_bytes / sizeof(data); + + if (count > (1U) << 19) { + // Size is too large, must be strictly less than 512 KB. + return false; + } + + uint64 a1 = 1; + uint64 a2 = 1; + uint64 b1 = 0; + uint64 b2 = 0; + + unsigned int i = 0; + while (i < count) { + // Process 64 bits at a time. + data.l64 = data64[i]; + a1 = a1 + data.l32.l; + b1 = b1 + a1; + a1 = a1 + data.l32.h; + b1 = b1 + a1; + i++; + + data.l64 = data64[i]; + a2 = a2 + data.l32.l; + b2 = b2 + a2; + a2 = a2 + data.l32.h; + b2 = b2 + a2; + i++; + } + checksum->Set(a1, a2, b1, b2); + return true; +} + +// C implementation of Adler memory copy. +bool AdlerMemcpyC(uint64 *dstmem64, uint64 *srcmem64, + unsigned int size_in_bytes, AdlerChecksum *checksum) { + // Use this data wrapper to access memory with 64bit read/write. + datacast_t data; + unsigned int count = size_in_bytes / sizeof(data); + + if (count > ((1U) << 19)) { + // Size is too large, must be strictly less than 512 KB. + return false; + } + + uint64 a1 = 1; + uint64 a2 = 1; + uint64 b1 = 0; + uint64 b2 = 0; + + unsigned int i = 0; + while (i < count) { + // Process 64 bits at a time. + data.l64 = srcmem64[i]; + a1 = a1 + data.l32.l; + b1 = b1 + a1; + a1 = a1 + data.l32.h; + b1 = b1 + a1; + dstmem64[i] = data.l64; + i++; + + data.l64 = srcmem64[i]; + a2 = a2 + data.l32.l; + b2 = b2 + a2; + a2 = a2 + data.l32.h; + b2 = b2 + a2; + dstmem64[i] = data.l64; + i++; + } + checksum->Set(a1, a2, b1, b2); + return true; +} + +// C implementation of Adler memory copy with some float point ops, +// attempting to warm up the CPU. +bool AdlerMemcpyWarmC(uint64 *dstmem64, uint64 *srcmem64, + unsigned int size_in_bytes, AdlerChecksum *checksum) { + // Use this data wrapper to access memory with 64bit read/write. + datacast_t data; + unsigned int count = size_in_bytes / sizeof(data); + + if (count > ((1U) << 19)) { + // Size is too large, must be strictly less than 512 KB. + return false; + } + + uint64 a1 = 1; + uint64 a2 = 1; + uint64 b1 = 0; + uint64 b2 = 0; + + double a = 2.0 * static_cast(srcmem64[0]); + double b = 5.0 * static_cast(srcmem64[0]); + double c = 7.0 * static_cast(srcmem64[0]); + double d = 9.0 * static_cast(srcmem64[0]); + + unsigned int i = 0; + while (i < count) { + // Process 64 bits at a time. + data.l64 = srcmem64[i]; + a1 = a1 + data.l32.l; + b1 = b1 + a1; + a1 = a1 + data.l32.h; + b1 = b1 + a1; + dstmem64[i] = data.l64; + i++; + + // Warm cpu up. + a = a * b; + b = b + c; + + data.l64 = srcmem64[i]; + a2 = a2 + data.l32.l; + b2 = b2 + a2; + a2 = a2 + data.l32.h; + b2 = b2 + a2; + dstmem64[i] = data.l64; + i++; + + // Warm cpu up. + c = c * d; + d = d + d; + } + + // Warm cpu up. + d = a + b + c + d; + if (d == 1.0) { + // Reference the result so that it can't be discarded by the compiler. + printf("Log: This will probably never happen.\n"); + } + + checksum->Set(a1, a2, b1, b2); + return true; +} + +// x86_64 SSE2 assembly implementation of fast and stressful Adler memory copy. +bool AdlerMemcpyAsm(uint64 *dstmem64, uint64 *srcmem64, + unsigned int size_in_bytes, AdlerChecksum *checksum) { +// Use assembly implementation only with 64bit compilation. +#ifndef STRESSAPPTEST_CPU_X86_64 + // Fall back to C implementation for 32bit compilation. + return AdlerMemcpyWarmC(dstmem64, srcmem64, size_in_bytes, checksum); +#else + // Elements 0 to 3 are used for holding checksum terms a1, a2, + // b1, b2 respectively. These elements are filled by asm code. + // Elements 4 and 5 are used by asm code to for ANDing MMX data and removing + // 2 words from each MMX register (A MMX reg has 4 words, by ANDing we are + // setting word index 0 and word index 2 to zero). + // Element 6 and 7 are used for setting a1 and a2 to 1. + volatile uint64 checksum_arr[] = {0, 0, 0, 0, + 0x00000000ffffffffUL, 0x00000000ffffffffUL, 1, 1}; + + if ((size_in_bytes >> 19) > 0) { + // Size is too large. Must be less than 2^19 bytes = 512 KB. + return false; + } + + // Number of 32-bit words which are not added to a1/a2 in the main loop. + uint64 remaining_words = (size_in_bytes % 48) / 4; + + // Since we are moving 48 bytes at a time number of iterations = total size/48 + // is value of counter. + uint64 num_of_48_byte_units = size_in_bytes / 48; + + asm volatile( + // Source address is in ESI (extended source index) + // destination is in EDI (extended destination index) + // and counter is already in ECX (extended counter index). + "cmp $0, %%ecx;" // Compare counter to zero. + "jz END;" + + // XMM6 is initialized with 1 and XMM7 with 0. + "prefetchnta 0(%%rsi);" + "prefetchnta 64(%%rsi);" + "movdqu 48(%%rax), %%xmm6;" + "xorps %%xmm7, %%xmm7;" + + // Start of the loop which copies 48 bytes from source to dst each time. + "TOP:\n" + + // Make 6 moves each of 16 bytes from srcmem to XMM registers. + // We are using 2 words out of 4 words in each XMM register, + // word index 0 and word index 2) + "movdqa 0(%%rsi), %%xmm0;" + "movdqu 4(%%rsi), %%xmm1;" // Be careful to use unaligned move here. + "movdqa 16(%%rsi), %%xmm2;" + "movdqu 20(%%rsi), %%xmm3;" + "movdqa 32(%%rsi), %%xmm4;" + "movdqu 36(%%rsi), %%xmm5;" + + // Move 3 * 16 bytes from XMM registers to dstmem. + // Note: this copy must be performed before pinsrw instructions since + // they will modify the XMM registers. + "movntdq %%xmm0, 0(%%rdi);" + "movntdq %%xmm2, 16(%%rdi);" + "movntdq %%xmm4, 32(%%rdi);" + + // Sets the word[1] and word[3] of XMM0 to XMM5 to zero. + "andps 32(%%rax), %%xmm0;" + "andps 32(%%rax), %%xmm1;" + "andps 32(%%rax), %%xmm2;" + "andps 32(%%rax), %%xmm3;" + "andps 32(%%rax), %%xmm4;" + "andps 32(%%rax), %%xmm5;" + + // Add XMM0 to XMM6 and then add XMM6 to XMM7. + // Repeat this for XMM1, ..., XMM5. + // Overflow(for XMM7) can occur only if there are more + // than 2^16 additions => more than 2^17 words => more than 2^19 bytes so + // if size_in_bytes > 2^19 than overflow occurs. + "paddq %%xmm0, %%xmm6;" + "paddq %%xmm6, %%xmm7;" + "paddq %%xmm1, %%xmm6;" + "paddq %%xmm6, %%xmm7;" + "paddq %%xmm2, %%xmm6;" + "paddq %%xmm6, %%xmm7;" + "paddq %%xmm3, %%xmm6;" + "paddq %%xmm6, %%xmm7;" + "paddq %%xmm4, %%xmm6;" + "paddq %%xmm6, %%xmm7;" + "paddq %%xmm5, %%xmm6;" + "paddq %%xmm6, %%xmm7;" + + // Increment ESI and EDI by 48 bytes and decrement counter by 1. + "add $48, %%rsi;" + "add $48, %%rdi;" + "prefetchnta 0(%%rsi);" + "prefetchnta 64(%%rsi);" + "dec %%rcx;" + "jnz TOP;" + + // Now only remaining_words 32-bit words are left. + // make a loop, add first two words to a1 and next two to a2 (just like + // above loop, the only extra thing we are doing is rechecking + // %rdx (=remaining_words) everytime we add a number to a1/a2. + "REM_IS_STILL_NOT_ZERO:\n" + // Unless remaining_words becomes less than 4 words(16 bytes) + // there is not much issue and remaining_words will always + // be a multiple of four by assumption. + "cmp $4, %%rdx;" + // In case for some weird reasons if remaining_words becomes + // less than 4 but not zero then also break the code and go off to END. + "jl END;" + // Otherwise just go on and copy data in chunks of 4-words at a time till + // whole data (<48 bytes) is copied. + "movdqa 0(%%rsi), %%xmm0;" // Copy next 4-words to XMM0 and to XMM1. + + "movdqa 0(%%rsi), %%xmm5;" // Accomplish movdqu 4(%%rsi) without + "pshufd $0x39, %%xmm5, %%xmm1;" // indexing off memory boundary. + + "movntdq %%xmm0, 0(%%rdi);" // Copy 4-words to destination. + "andps 32(%%rax), %%xmm0;" + "andps 32(%%rax), %%xmm1;" + "paddq %%xmm0, %%xmm6;" + "paddq %%xmm6, %%xmm7;" + "paddq %%xmm1, %%xmm6;" + "paddq %%xmm6, %%xmm7;" + "add $16, %%rsi;" + "add $16, %%rdi;" + "sub $4, %%rdx;" + // Decrement %%rdx by 4 since %%rdx is number of 32-bit + // words left after considering all 48-byte units. + "jmp REM_IS_STILL_NOT_ZERO;" + + "END:\n" + // Report checksum values A and B (both right now are two concatenated + // 64 bit numbers and have to be converted to 64 bit numbers) + // seems like Adler128 (since size of each part is 4 byte rather than + // 1 byte). + "movdqa %%xmm6, 0(%%rax);" + "movdqa %%xmm7, 16(%%rax);" + "sfence;" + + // No output registers. + : + // Input registers. + : "S" (srcmem64), "D" (dstmem64), "a" (checksum_arr), + "c" (num_of_48_byte_units), "d" (remaining_words) + ); // asm. + + if (checksum != NULL) { + checksum->Set(checksum_arr[0], checksum_arr[1], + checksum_arr[2], checksum_arr[3]); + } + + // Everything went fine, so return true (this does not mean + // that there is no problem with memory this just mean that data was copied + // from src to dst and checksum was calculated successfully). + return true; +#endif +} diff --git a/src/adler32memcpy.h b/src/adler32memcpy.h new file mode 100644 index 0000000..d053340 --- /dev/null +++ b/src/adler32memcpy.h @@ -0,0 +1,59 @@ +// Copyright 2008 Google Inc. All Rights Reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef STRESSAPPTEST_ADLER32MEMCPY_H_ +#define STRESSAPPTEST_ADLER32MEMCPY_H_ + +#include +#include "sattypes.h" + +// Encapsulation for Adler checksum. Please see adler32memcpy.cc for more +// detail on the adler checksum algorithm. +class AdlerChecksum { + public: + AdlerChecksum() {} + ~AdlerChecksum() {} + // Returns true if the checksums are equal. + bool Equals(const AdlerChecksum &other) const; + // Returns string representation of the Adler checksum + string ToHexString() const; + // Sets components of the Adler checksum. + void Set(uint64 a1, uint64 a2, uint64 b1, uint64 b2); + + private: + // Components of Adler checksum. + uint64 a1_, a2_, b1_, b2_; + + DISALLOW_COPY_AND_ASSIGN(AdlerChecksum); +}; + +// Calculates Adler checksum for supplied data. +bool CalculateAdlerChecksum(uint64 *data64, unsigned int size_in_bytes, + AdlerChecksum *checksum); + +// C implementation of Adler memory copy. +bool AdlerMemcpyC(uint64 *dstmem64, uint64 *srcmem64, + unsigned int size_in_bytes, AdlerChecksum *checksum); + +// C implementation of Adler memory copy with some float point ops, +// attempting to warm up the CPU. +bool AdlerMemcpyWarmC(uint64 *dstmem64, uint64 *srcmem64, + unsigned int size_in_bytes, AdlerChecksum *checksum); + +// x86_64 SSE2 assembly implementation of fast and stressful Adler memory copy. +bool AdlerMemcpyAsm(uint64 *dstmem64, uint64 *srcmem64, + unsigned int size_in_bytes, AdlerChecksum *checksum); + + +#endif // STRESSAPPTEST_ADLER32MEMCPY_H_ diff --git a/src/disk_blocks.cc b/src/disk_blocks.cc new file mode 100644 index 0000000..c7860b0 --- /dev/null +++ b/src/disk_blocks.cc @@ -0,0 +1,313 @@ +// Copyright 2008 Google Inc. All Rights Reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Thread-safe container of disk blocks + +#include + +// This file must work with autoconf on its public version, +// so these includes are correct. +#include "disk_blocks.h" + +DiskBlockTable::DiskBlockTable() { + nelems_ = 0; + pthread_mutex_init(&data_mutex_, NULL); + pthread_mutex_init(¶meter_mutex_, NULL); + pthread_cond_init(&data_condition_, NULL); +} + +DiskBlockTable::~DiskBlockTable() { + CleanTable(); + pthread_mutex_destroy(&data_mutex_); + pthread_mutex_destroy(¶meter_mutex_); + pthread_cond_destroy(&data_condition_); +} + +void DiskBlockTable::CleanTable() { + pthread_mutex_lock(&data_mutex_); + for (map::iterator it = + addr_to_block_.begin(); it != addr_to_block_.end(); ++it) { + delete it->second; + } + addr_to_block_.erase(addr_to_block_.begin(), addr_to_block_.end()); + nelems_ = 0; + pthread_cond_broadcast(&data_condition_); + pthread_mutex_unlock(&data_mutex_); +} + +// 64-bit non-negative random number generator. Stolen from +// depot/google3/base/tracecontext_unittest.cc. +int64 DiskBlockTable::Random64() { + int64 x = random(); + x = (x << 30) ^ random(); + x = (x << 30) ^ random(); + if (x >= 0) + return x; + else + return -x; +} + +int64 DiskBlockTable::NumElems() { + unsigned int nelems; + pthread_mutex_lock(&data_mutex_); + nelems = nelems_; + pthread_mutex_unlock(&data_mutex_); + return nelems; +} + +void DiskBlockTable::InsertOnStructure(BlockData *block) { + int64 address = block->GetAddress(); + StorageData *sd = new StorageData(); + sd->block = block; + sd->pos = nelems_; + // Creating new block ... + pthread_mutex_lock(&data_mutex_); + if (pos_to_addr_.size() <= nelems_) { + pos_to_addr_.insert(pos_to_addr_.end(), address); + } else { + pos_to_addr_[nelems_] = address; + } + addr_to_block_.insert(std::make_pair(address, sd)); + nelems_++; + pthread_cond_broadcast(&data_condition_); + pthread_mutex_unlock(&data_mutex_); +} + +int DiskBlockTable::RemoveBlock(BlockData *block) { + // For write threads, check the reference counter and remove + // it from the structure. + int64 address = block->GetAddress(); + AddrToBlockMap::iterator it = addr_to_block_.find(address); + int ret = 1; + if (it != addr_to_block_.end()) { + int curr_pos = it->second->pos; + int last_pos = nelems_ - 1; + AddrToBlockMap::iterator last_it = addr_to_block_.find( + pos_to_addr_[last_pos]); + sat_assert(nelems_ > 0); + sat_assert(last_it != addr_to_block_.end()); + // Everything is fine, updating ... + pthread_mutex_lock(&data_mutex_); + pos_to_addr_[curr_pos] = pos_to_addr_[last_pos]; + last_it->second->pos = curr_pos; + delete it->second; + addr_to_block_.erase(it); + nelems_--; + block->DecreaseReferenceCounter(); + if (block->GetReferenceCounter() == 0) + delete block; + pthread_cond_broadcast(&data_condition_); + pthread_mutex_unlock(&data_mutex_); + } else { + ret = 0; + } + return ret; +} + +int DiskBlockTable::ReleaseBlock(BlockData *block) { + // If is a random thread, just check the reference counter. + int ret = 1; + pthread_mutex_lock(&data_mutex_); + int references = block->GetReferenceCounter(); + if (references > 0) { + if (references == 1) + delete block; + else + block->DecreaseReferenceCounter(); + } else { + ret = 0; + } + pthread_mutex_unlock(&data_mutex_); + return ret; +} + +BlockData *DiskBlockTable::GetRandomBlock() { + struct timespec ts; + struct timeval tp; + int result = 0; + gettimeofday(&tp, NULL); + ts.tv_sec = tp.tv_sec; + ts.tv_nsec = tp.tv_usec * 1000; + ts.tv_sec += 2; // Wait for 2 seconds. + pthread_mutex_lock(&data_mutex_); + while (!nelems_ && result != ETIMEDOUT) { + result = pthread_cond_timedwait(&data_condition_, &data_mutex_, &ts); + } + if (result == ETIMEDOUT) { + pthread_mutex_unlock(&data_mutex_); + return NULL; + } else { + int64 random_number = Random64(); + int64 random_pos = random_number % nelems_; + int64 address = pos_to_addr_[random_pos]; + AddrToBlockMap::const_iterator it = addr_to_block_.find(address); + sat_assert(it != addr_to_block_.end()); + BlockData *b = it->second->block; + // A block is returned only if its content is written on disk. + if (b->BlockIsInitialized()) { + b->IncreaseReferenceCounter(); + } else { + b = NULL; + } + pthread_mutex_unlock(&data_mutex_); + return b; + } +} + +void DiskBlockTable::SetParameters( + int sector_size, int write_block_size, int64 device_sectors, + int64 segment_size, string device_name) { + pthread_mutex_lock(¶meter_mutex_); + sector_size_ = sector_size; + write_block_size_ = write_block_size; + device_sectors_ = device_sectors; + segment_size_ = segment_size; + device_name_ = device_name; + CleanTable(); + pthread_mutex_unlock(¶meter_mutex_); +} + +BlockData *DiskBlockTable::GetUnusedBlock(int64 segment) { + int64 sector = 0; + BlockData *block = new BlockData(); + + bool good_sequence = false; + int num_sectors; + + if (block == NULL) { + logprintf(0, "Process Error: Unable to allocate memory " + "for sector data for disk %s.\n", device_name_.c_str()); + return NULL; + } + + pthread_mutex_lock(¶meter_mutex_); + + sat_assert(device_sectors_ != 0); + + // Align the first sector with the beginning of a write block + num_sectors = write_block_size_ / sector_size_; + + for (int i = 0; i < kBlockRetry && !good_sequence; i++) { + good_sequence = true; + + // Use the entire disk or a small segment of the disk to allocate the first + // sector in the block from. + + if (segment_size_ == -1) { + sector = (Random64() & 0x7FFFFFFFFFFFFFFFLL) % ( + device_sectors_ / num_sectors); + sector *= num_sectors; + } else { + sector = (Random64() & 0x7FFFFFFFFFFFFFFFLL) % ( + segment_size_ / num_sectors); + sector *= num_sectors; + sector += segment * segment_size_; + + // Make sure the block is within the segment. + if (sector + num_sectors > (segment + 1) * segment_size_) { + good_sequence = false; + continue; + } + } + // Make sure the entire block is in range. + if (sector + num_sectors > device_sectors_) { + good_sequence = false; + continue; + } + // Check to see if the block is free. Since the blocks are + // now aligned to the write_block_size, it is not necessary + // to check each sector, just the first block (a sector + // overlap will never occur). + + pthread_mutex_lock(&data_mutex_); + if (addr_to_block_.find(sector) != addr_to_block_.end()) { + good_sequence = false; + } + pthread_mutex_unlock(&data_mutex_); + } + + if (good_sequence) { + block->SetParameters(sector, write_block_size_); + block->IncreaseReferenceCounter(); + InsertOnStructure(block); + } else { + // No contiguous sequence of num_sectors sectors was found within + // kBlockRetry iterations so return an error value. + delete block; + block = NULL; + } + pthread_mutex_unlock(¶meter_mutex_); + + return block; +} + +// BlockData + +BlockData::BlockData() { + addr_ = 0; + size_ = 0; + references_ = 0; + initialized_ = false; + pthread_mutex_init(&data_mutex_, NULL); +} + +BlockData::~BlockData() { + pthread_mutex_destroy(&data_mutex_); +} + +void BlockData::SetParameters(int64 address, int64 size) { + addr_ = address; + size_ = size; +} + +void BlockData::IncreaseReferenceCounter() { + references_++; +} + +void BlockData::DecreaseReferenceCounter() { + references_--; +} + +int BlockData::GetReferenceCounter() { + return references_; +} + +void BlockData::SetBlockAsInitialized() { + pthread_mutex_lock(&data_mutex_); + initialized_ = true; + pthread_mutex_unlock(&data_mutex_); +} + +bool BlockData::BlockIsInitialized() { + pthread_mutex_lock(&data_mutex_); + bool initialized = initialized_; + pthread_mutex_unlock(&data_mutex_); + return initialized; +} + +int64 BlockData::GetAddress() { + return addr_; +} + +int64 BlockData::GetSize() { + return size_; +} + +Pattern *BlockData::GetPattern() { + return pattern_; +} + +void BlockData::SetPattern(Pattern *p) { + pattern_ = p; +} diff --git a/src/disk_blocks.h b/src/disk_blocks.h new file mode 100644 index 0000000..f4ca93f --- /dev/null +++ b/src/disk_blocks.h @@ -0,0 +1,115 @@ +// Copyright 2008 Google Inc. All Rights Reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Interface for a thread-safe container of disk blocks + +#ifndef STRESSAPPTEST_DISK_BLOCKS_H_ +#define STRESSAPPTEST_DISK_BLOCKS_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +// This file must work with autoconf on its public version, +// so these includes are correct. +#include "pattern.h" + +// Data about a block written to disk so that it can be verified later. +class BlockData { + public: + BlockData(); + ~BlockData(); + void SetParameters(int64 address, int64 size); + void IncreaseReferenceCounter(); + void DecreaseReferenceCounter(); + int GetReferenceCounter(); + void SetBlockAsInitialized(); + bool BlockIsInitialized(); + int64 GetAddress(); + int64 GetSize(); + void SetPattern(Pattern *p); + Pattern *GetPattern(); + protected: + int64 addr_; // address of first sector in block + int64 size_; // size of block + int references_; // reference counter + bool initialized_; // flag indicating the block was written on disk + Pattern *pattern_; + pthread_mutex_t data_mutex_; + DISALLOW_COPY_AND_ASSIGN(BlockData); +}; + +// Disk Block table - store data from blocks to be write / read by +// a DiskThread +class DiskBlockTable { + public: + DiskBlockTable(); + virtual ~DiskBlockTable(); + + // Get Number of elements stored on table + int64 NumElems(); + // Clean all table data + void CleanTable(); + // Get a random block from the list. Only returns if a element + // is available (consider that other thread must have added them. + BlockData *GetRandomBlock(); + // Set all initial parameters. Assumes all existent data is + // invalid and, therefore, must be removed. + void SetParameters(int sector_size, int write_block_size, + int64 device_sectors, + int64 segment_size, + string device_name); + // Return a new block in a unused address. + BlockData *GetUnusedBlock(int64 segment); + // Remove block from structure (called by write threads) + int RemoveBlock(BlockData *block); + // Release block to be erased (called by random threads) + int ReleaseBlock(BlockData *block); + + protected: + + void InsertOnStructure(BlockData *block); + // Generate a random 64-bit integer (virtual so it could be + // override by the tests) + virtual int64 Random64(); + + struct StorageData { + BlockData *block; + int pos; + }; + + static const int kBlockRetry = 100; // Number of retries to allocate + // sectors. + + typedef map AddrToBlockMap; + typedef vector PosToAddrVector; + PosToAddrVector pos_to_addr_; + AddrToBlockMap addr_to_block_; + int64 nelems_; + int sector_size_; // Sector size, in bytes + int write_block_size_; // Block size, in bytes + string device_name_; // Device name + int64 device_sectors_; // Number of sectors in device + int64 segment_size_; // Segment size, in bytes + pthread_mutex_t data_mutex_; + pthread_cond_t data_condition_; + pthread_mutex_t parameter_mutex_; + DISALLOW_COPY_AND_ASSIGN(DiskBlockTable); +}; + +#endif // STRESSAPPTEST_BLOCKS_H_ diff --git a/src/error_diag.cc b/src/error_diag.cc new file mode 100644 index 0000000..53f056f --- /dev/null +++ b/src/error_diag.cc @@ -0,0 +1,317 @@ +// Copyright 2008 Google Inc. All Rights Reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// error_diag.cc: Collects device errors for analysis to more accurately +// pin-point failed component. + +#include +#include +#include + +// This file must work with autoconf on its public version, +// so these includes are correct. +#include "error_diag.h" +#include "sattypes.h" + + +// DeviceTree constructor. +DeviceTree::DeviceTree(string name) + : parent_(0), name_(name) { + pthread_mutex_init(&device_tree_mutex_, NULL); +} + +// DeviceTree destructor. +DeviceTree::~DeviceTree() { + // Deallocate subtree devices. + for (std::map::iterator itr = subdevices_.begin(); + itr != subdevices_.end(); + ++itr) { + delete itr->second; + } + // Deallocate device errors. + for (std::list::iterator itr = errors_.begin(); + itr != errors_.end(); + ++itr) { + delete (*itr); + } + pthread_mutex_destroy(&device_tree_mutex_); +} + +// Atomically find named device in sub device tree. +// Returns 0 if not found +DeviceTree *DeviceTree::FindInSubTree(string name) { + DeviceTree *ret; + pthread_mutex_lock(&device_tree_mutex_); + ret = UnlockedFindInSubTree(name); + pthread_mutex_unlock(&device_tree_mutex_); + return ret; +} + +// Find named device in sub device tree (Non-atomic). +// Returns 0 if not found +DeviceTree *DeviceTree::UnlockedFindInSubTree(string name) { + std::map::iterator itr = subdevices_.find(name); + if (itr != subdevices_.end()) { + return itr->second; + } else { + // Search sub-tree. + for (std::map::iterator itr = subdevices_.begin(); + itr != subdevices_.end(); + ++itr) { + DeviceTree *result = itr->second->UnlockedFindInSubTree(name); + if (result != 0) + return result; + } + return 0; + } +} + +// Atomically add error instance to device. +void DeviceTree::AddErrorInstance(ErrorInstance *error_instance) { + pthread_mutex_lock(&device_tree_mutex_); + errors_.push_back(error_instance); + pthread_mutex_unlock(&device_tree_mutex_); +} + +// Find or add queried device as necessary. +DeviceTree *DeviceTree::FindOrAddDevice(string name) { + // Assume named device does not exist and try to insert the device anyway. + // No-op if named device already exists. + InsertSubDevice(name); + // Find and return sub device pointer. + return FindInSubTree(name); +} + +// Pretty prints device tree. +void DeviceTree::PrettyPrint(string spacer) { + for (std::map::iterator itr = subdevices_.begin(); + itr != subdevices_.end(); + ++itr) { + printf("%s%s\n", spacer.c_str(), itr->first.c_str()); + itr->second->PrettyPrint(spacer+spacer); + } +} + +// Atomically add sub device. +// No-op if named device already exists. +void DeviceTree::InsertSubDevice(string name) { + pthread_mutex_lock(&device_tree_mutex_); + if (UnlockedFindInSubTree(name) != 0) { + pthread_mutex_unlock(&device_tree_mutex_); + return; + } + subdevices_[name] = new DeviceTree(name); + subdevices_[name]->parent_ = this; + pthread_mutex_unlock(&device_tree_mutex_); +} + + +// Returns true of any error associated with this device is fatal. +bool DeviceTree::KnownBad() { + pthread_mutex_lock(&device_tree_mutex_); + for (std::list::iterator itr = errors_.begin(); + itr != errors_.end(); + ++itr) { + if ((*itr)->severity_ == SAT_ERROR_FATAL) { + pthread_mutex_unlock(&device_tree_mutex_); + return true; + } + } + pthread_mutex_unlock(&device_tree_mutex_); + return false; +} + + +// ErrorDiag constructor. +ErrorDiag::ErrorDiag() { + os_ = 0; + system_tree_root_ = 0; +} + +// ErrorDiag destructor. +ErrorDiag::~ErrorDiag() { + if (system_tree_root_) + delete system_tree_root_; +} + +// Set platform specific handle and initialize device tree. +// Returns false on error. true otherwise. +bool ErrorDiag::set_os(OsLayer *os) { + os_ = os; + return(InitializeDeviceTree()); +} + +// Create and initialize system device tree. +// Returns false on error. true otherwise. +bool ErrorDiag::InitializeDeviceTree() { + system_tree_root_ = new DeviceTree("system_root"); + if (!system_tree_root_) + return false; + return true; +} + +// Logs info about a CECC. +// Returns -1 on error, 1 if diagnoser reports error externally; 0 otherwise. +int ErrorDiag::AddCeccError(string dimm_string) { + DeviceTree *dimm_device = system_tree_root_->FindOrAddDevice(dimm_string); + ECCErrorInstance *error = new ECCErrorInstance; + if (!error) + return -1; + error->severity_ = SAT_ERROR_CORRECTABLE; + dimm_device->AddErrorInstance(error); + return 0; +} + +// Logs info about a UECC. +// Returns -1 on error, 1 if diagnoser reports error externally; 0 otherwise. +int ErrorDiag::AddUeccError(string dimm_string) { + DeviceTree *dimm_device = system_tree_root_->FindOrAddDevice(dimm_string); + ECCErrorInstance *error = new ECCErrorInstance; + if (!error) + return -1; + error->severity_ = SAT_ERROR_FATAL; + dimm_device->AddErrorInstance(error); + return 0; +} + +// Logs info about a miscompare. +// Returns -1 on error, 1 if diagnoser reports error externally; 0 otherwise. +int ErrorDiag::AddMiscompareError(string dimm_string, uint64 addr, int count) { + DeviceTree *dimm_device = system_tree_root_->FindOrAddDevice(dimm_string); + MiscompareErrorInstance *error = new MiscompareErrorInstance; + if (!error) + return -1; + error->severity_ = SAT_ERROR_FATAL; + error->addr_ = addr; + dimm_device->AddErrorInstance(error); + os_->ErrorReport(dimm_string.c_str(), "miscompare", count); + return 1; +} + +// Utility Function to translate a virtual address to DIMM number. +// Returns -1 on error, 1 if diagnoser reports error externally; 0 otherwise. +string ErrorDiag::AddressToDimmString(OsLayer *os, void *addr, int offset) { + char dimm_string[256] = ""; + char *vbyteaddr = reinterpret_cast(addr) + offset; + uint64 paddr = os->VirtualToPhysical(vbyteaddr); + os->FindDimm(paddr, dimm_string, sizeof(dimm_string)); + return string(dimm_string); +} + +// Info about a miscompare from a drive. +// Returns -1 on error, 1 if diagnoser reports error externally; 0 otherwise. +int ErrorDiag::AddHDDMiscompareError(string devicename, int block, int offset, + void *src_addr, void *dst_addr) { + bool mask_hdd_error = false; + + HDDMiscompareErrorInstance *error = new HDDMiscompareErrorInstance; + if (!error) + return -1; + + error->addr_ = reinterpret_cast(src_addr); + error->addr2_ = reinterpret_cast(dst_addr); + error->offset_ = offset; + error->block_ = block; + + string src_dimm = AddressToDimmString(os_, src_addr, offset); + string dst_dimm = AddressToDimmString(os_, dst_addr, offset); + + // DIMM name look up success + if (src_dimm.compare("DIMM Unknown")) { + // Add src DIMM as possible miscompare cause. + DeviceTree *src_dimm_dev = system_tree_root_->FindOrAddDevice(src_dimm); + error->causes_.insert(src_dimm_dev); + if (src_dimm_dev->KnownBad()) { + mask_hdd_error = true; + logprintf(5, "Log: supressed %s miscompare report: " + "known bad source: %s\n", devicename.c_str(), src_dimm.c_str()); + } + } + if (dst_dimm.compare("DIMM Unknown")) { + // Add dst DIMM as possible miscompare cause. + DeviceTree *dst_dimm_dev = system_tree_root_->FindOrAddDevice(dst_dimm); + error->causes_.insert(dst_dimm_dev); + if (dst_dimm_dev->KnownBad()) { + mask_hdd_error = true; + logprintf(5, "Log: supressed %s miscompare report: " + "known bad destination: %s\n", devicename.c_str(), + dst_dimm.c_str()); + } + } + + DeviceTree *hdd_dev = system_tree_root_->FindOrAddDevice(devicename); + hdd_dev->AddErrorInstance(error); + + // HDD error was not masked by bad DIMMs: report bad HDD. + if (!mask_hdd_error) { + os_->ErrorReport(devicename.c_str(), "miscompare", 1); + error->severity_ = SAT_ERROR_FATAL; + return 1; + } + return 0; +} + +// Info about a sector tag miscompare from a drive. +// Returns -1 on error, 1 if diagnoser reports error externally; 0 otherwise. +int ErrorDiag::AddHDDSectorTagError(string devicename, int block, int offset, + int sector, void *src_addr, + void *dst_addr) { + bool mask_hdd_error = false; + + HDDSectorTagErrorInstance *error = new HDDSectorTagErrorInstance; + if (!error) + return -1; + + error->addr_ = reinterpret_cast(src_addr); + error->addr2_ = reinterpret_cast(dst_addr); + error->sector_ = sector; + error->block_ = block; + + string src_dimm = AddressToDimmString(os_, src_addr, offset); + string dst_dimm = AddressToDimmString(os_, dst_addr, offset); + + // DIMM name look up success + if (src_dimm.compare("DIMM Unknown")) { + // Add src DIMM as possible miscompare cause. + DeviceTree *src_dimm_dev = system_tree_root_->FindOrAddDevice(src_dimm); + error->causes_.insert(src_dimm_dev); + if (src_dimm_dev->KnownBad()) { + mask_hdd_error = true; + logprintf(5, "Log: supressed %s sector tag error report: " + "known bad source: %s\n", devicename.c_str(), src_dimm.c_str()); + } + } + if (dst_dimm.compare("DIMM Unknown")) { + // Add dst DIMM as possible miscompare cause. + DeviceTree *dst_dimm_dev = system_tree_root_->FindOrAddDevice(dst_dimm); + error->causes_.insert(dst_dimm_dev); + if (dst_dimm_dev->KnownBad()) { + mask_hdd_error = true; + logprintf(5, "Log: supressed %s sector tag error report: " + "known bad destination: %s\n", devicename.c_str(), + dst_dimm.c_str()); + } + } + + DeviceTree *hdd_dev = system_tree_root_->FindOrAddDevice(devicename); + hdd_dev->AddErrorInstance(error); + + // HDD error was not masked by bad DIMMs: report bad HDD. + if (!mask_hdd_error) { + os_->ErrorReport(devicename.c_str(), "sector", 1); + error->severity_ = SAT_ERROR_FATAL; + return 1; + } + return 0; +} diff --git a/src/error_diag.h b/src/error_diag.h new file mode 100644 index 0000000..7faedb8 --- /dev/null +++ b/src/error_diag.h @@ -0,0 +1,167 @@ +// Copyright 2008 Google Inc. All Rights Reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// error_diag.h: Ambiguous error diagnosis class + +#ifndef STRESSAPPTEST_ERROR_DIAG_H_ +#define STRESSAPPTEST_ERROR_DIAG_H_ + +#include +#include +#include +#include +#include + +// This file must work with autoconf on its public version, +// so these includes are correct. +#include "sattypes.h" +#include "os.h" + +class ErrorInstance; + +// This describes the components of the system. +class DeviceTree { + public: + explicit DeviceTree(string name); + ~DeviceTree(); + + // Atomically find arbitrary device in subtree. + DeviceTree *FindInSubTree(string name); + // Find or add named device. + DeviceTree *FindOrAddDevice(string name); + // Atomically add sub device. + void InsertSubDevice(string name); + // Returns parent device. + DeviceTree *GetParent() { return parent_; } + // Pretty prints device tree. + void PrettyPrint(string spacer = " "); + // Atomically add error instance to device. + void AddErrorInstance(ErrorInstance *error_instance); + // Returns true of device is known to be bad. + bool KnownBad(); + // Returns number of direct sub devices. + int NumDirectSubDevices() { return subdevices_.size(); } + + private: + // Unlocked version of FindInSubTree. + DeviceTree *UnlockedFindInSubTree(string name); + + std::map subdevices_; // Map of sub-devices. + std::list errors_; // Log of errors. + DeviceTree *parent_; // Pointer to parent device. + string name_; // Device name. + pthread_mutex_t device_tree_mutex_; // Mutex protecting device tree. +}; + + +// enum type for collected errors. +enum SATErrorType { + SAT_ERROR_NONE = 0, + SAT_ERROR_ECC, + SAT_ERROR_MISCOMPARE, + SAT_ERROR_SECTOR_TAG, +}; + +// enum type for error severity. +enum SATErrorSeverity { + SAT_ERROR_CORRECTABLE = 0, + SAT_ERROR_FATAL, +}; + +// This describes an error and it's likely causes. +class ErrorInstance { + public: + ErrorInstance(): type_(SAT_ERROR_NONE), severity_(SAT_ERROR_CORRECTABLE) {} + + SATErrorType type_; // Type of error: ECC, miscompare, sector. + SATErrorSeverity severity_; // Correctable, or fatal. + std::set causes_; // Devices that can cause this type of error. +}; + +// This describes ECC errors. +class ECCErrorInstance: public ErrorInstance { + public: + ECCErrorInstance() { type_ = SAT_ERROR_ECC; } + + uint64 addr_; // Address where error occured. +}; + +// This describes miscompare errors. +class MiscompareErrorInstance: public ErrorInstance { + public: + MiscompareErrorInstance() { type_ = SAT_ERROR_MISCOMPARE; } + + uint64 addr_; // Address where miscompare occured. +}; + +// This describes HDD miscompare errors. +class HDDMiscompareErrorInstance: public MiscompareErrorInstance { + public: + uint64 addr2_; // addr_ and addr2_ are src and dst memory addr. + int offset_; // offset. + int block_; // error block. +}; + +// This describes HDD miscompare errors. +class HDDSectorTagErrorInstance: public ErrorInstance { + public: + HDDSectorTagErrorInstance() { type_ = SAT_ERROR_SECTOR_TAG; } + + uint64 addr_; + uint64 addr2_; // addr_ and addr2_ are src and dst memory addr. + int sector_; // error sector. + int block_; // error block. +}; + +// Generic error storage and sorting class. +class ErrorDiag { + public: + ErrorDiag(); + virtual ~ErrorDiag(); + + // Add info about a CECC. + virtual int AddCeccError(string dimm_string); + + // Add info about a UECC. + virtual int AddUeccError(string dimm_string); + + // Add info about a miscompare. + virtual int AddMiscompareError(string dimm_string, uint64 addr, int count); + + // Add info about a miscompare from a drive. + virtual int AddHDDMiscompareError(string devicename, int block, int offset, + void *src_addr, void *dst_addr); + + // Add info about a sector tag miscompare from a drive. + virtual int AddHDDSectorTagError(string devicename, int block, int offset, + int sector, void *src_addr, void *dst_addr); + + // Set platform specific handle and initialize device tree. + bool set_os(OsLayer *os); + + protected: + // Create and initialize system device tree. + virtual bool InitializeDeviceTree(); + + // Utility Function to translate a virtual address to DIMM number. + string AddressToDimmString(OsLayer *os, void *addr, int offset); + + DeviceTree *system_tree_root_; // System device tree. + OsLayer *os_; // Platform handle. + + private: + DISALLOW_COPY_AND_ASSIGN(ErrorDiag); +}; + +#endif // STRESSAPPTEST_ERROR_DIAG_H_ diff --git a/src/finelock_queue.cc b/src/finelock_queue.cc new file mode 100644 index 0000000..27cc37d --- /dev/null +++ b/src/finelock_queue.cc @@ -0,0 +1,441 @@ +// Copyright 2007 Google Inc. All Rights Reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This is an interface to a simple thread safe container with fine-grain locks, +// used to hold data blocks and patterns. + +// This file must work with autoconf on its public version, +// so these includes are correct. +#include "finelock_queue.h" +#include "os.h" + +// Page entry queue implementation follows. +// Push and Get functions are analogous to lock and unlock operations on a given +// page entry, while preserving queue semantics. +// +// The actual 'queue' implementation is actually just an array. The entries are +// never shuffled or re-ordered like that of a real queue. Instead, Get +// functions return a random page entry of a given type and lock that particular +// page entry until it is unlocked by corresponding Put functions. +// +// In this implementation, a free page is those page entries where pattern is +// null (pe->pattern == 0) + + +// Constructor: Allocates memory and initialize locks. +FineLockPEQueue::FineLockPEQueue( + uint64 queuesize, int64 pagesize) { + q_size_ = queuesize; + pages_ = new struct page_entry[q_size_]; + pagelocks_ = new pthread_mutex_t[q_size_]; + page_size_ = pagesize; + + // What metric should we measure this run. + queue_metric_ = kTouch; + + { // Init all the page locks. + for (int64 i = 0; i < q_size_; i++) + pthread_mutex_init(&(pagelocks_[i]), NULL); + } + + { // Init the random number generator. + for (int i = 0; i < 4; i++) { + rand_seed_[i] = i + 0xbeef; + pthread_mutex_init(&(randlocks_[i]), NULL); + } + } + + // Try to make a linear congruential generator with our queue size. + // We need this to deterministically search all the queue (being able to find + // a single available element is a design requirement), but we don't want to + // cause any page to be more likley chosen than another. The previous + // sequential retry heavily biased pages at the beginning of a bunch, or + // isolated pages surrounded by unqualified ones. + int64 length = queuesize; + int64 modlength = length; + int64 a; + int64 c; + + if (length < 3) { + a = 1; + c = 1; + } else { + // Search for a nontrivial generator. + a = getA(length) % length; + // If this queue size doesn't have a nontrivial generator (where the + // multiplier is greater then one) we'll check increasing queue sizes, + // and discard out of bounds results. + while (a == 1) { + modlength++; + a = getA(modlength) % modlength; + } + c = getC(modlength); + } + + // This is our final generator. + a_ = a; + c_ = c; + modlength_ = modlength; +} + +// Part of building a linear congruential generator n1 = (a * n0 + c) % m +// Get 'a', where a - 1 must be divisible by all prime +// factors of 'm', our queue size. +int64 FineLockPEQueue::getA(int64 m) { + int64 remaining = m; + int64 a = 1; + if ((((remaining / 4) * 4) == remaining)) { + a = 2; + } + // For each number, let's see if it's divisible, + // then divide it out. + for (int64 i = 2; i <= m; i++) { + if (((remaining / i) * i) == remaining) { + remaining /= i; + // Keep dividing it out until there's no more. + while (((remaining / i) * i) == remaining) + remaining /= i; + a *= i; + } + } + + // Return 'a' as specified. + return (a + 1) % m; +} + + +// Part of building a linear congruential generator n1 = (a * n0 + c) % m +// Get a prime number approx 3/4 the size of our queue. +int64 FineLockPEQueue::getC(int64 m) { + // Start here at 3/4. + int64 start = (3 * m) / 4 + 1; + int64 possible_prime = start; + // Keep trying until we find a prime. + for (possible_prime = start; possible_prime > 1; possible_prime--) { + bool failed = false; + for (int64 i = 2; i < possible_prime; i++) { + if (((possible_prime / i) * i) == possible_prime) { + failed = true; + break; + } + } + if (!failed) { + return possible_prime; + } + } + // One is prime enough. + return 1; +} + +// Destructor: Clean-up allocated memory and destroy pthread locks. +FineLockPEQueue::~FineLockPEQueue() { + int64 i; + for (i = 0; i < q_size_; i++) + pthread_mutex_destroy(&(pagelocks_[i])); + delete[] pagelocks_; + delete[] pages_; + for (i = 0; i < 4; i++) { + pthread_mutex_destroy(&(randlocks_[i])); + } +} + + +bool FineLockPEQueue::QueueAnalysis() { + const char *measurement = "Error"; + uint64 buckets[32]; + + if (queue_metric_ == kTries) + measurement = "Failed retrievals"; + else if (queue_metric_ == kTouch) + measurement = "Reads per page"; + + // Buckets for each log2 access counts. + for (int b = 0; b < 32; b++) { + buckets[b] = 0; + } + + // Bucketize the page counts by highest bit set. + for (int64 i = 0; i < q_size_; i++) { + uint32 readcount = pages_[i].touch; + int b = 0; + for (b = 0; b < 31; b++) { + if (readcount < (1 << b)) + break; + } + + buckets[b]++; + } + + logprintf(12, "Log: %s histogram\n", measurement); + for (int b = 0; b < 32; b++) { + if (buckets[b]) + logprintf(12, "Log: %12d - %12d: %12d\n", + ((1 << b) >> 1), 1 << b, buckets[b]); + } + + return true; +} + +namespace { +// Callback mechanism for exporting last action. +OsLayer *g_os; +FineLockPEQueue *g_fpqueue = 0; + +// Global callback to hook into Os object. +bool err_log_callback(uint64 paddr, string *buf) { + if (g_fpqueue) { + return g_fpqueue->ErrorLogCallback(paddr, buf); + } + return false; +} +} + +// Setup global state for exporting callback. +void FineLockPEQueue::set_os(OsLayer *os) { + g_os = os; + g_fpqueue = this; +} + +OsLayer::ErrCallback FineLockPEQueue::get_err_log_callback() { + return err_log_callback; +} + +// This call is used to export last transaction info on a particular physical +// address. +bool FineLockPEQueue::ErrorLogCallback(uint64 paddr, string *message) { + struct page_entry pe; + OsLayer *os = g_os; + sat_assert(g_os); + char buf[256]; + + // Find the page of this paddr. + int gotpage = GetPageFromPhysical(paddr, &pe); + if (!gotpage) { + return false; + } + + // Find offset into the page. + uint64 addr_diff = paddr - pe.paddr; + + // Find vaddr of this paddr. Make sure it matches, + // as sometimes virtual memory is not contiguous. + char *vaddr = + reinterpret_cast(os->PrepareTestMem(pe.offset, page_size_)); + uint64 new_paddr = os->VirtualToPhysical(vaddr + addr_diff); + os->ReleaseTestMem(vaddr, pe.offset, page_size_); + + // Is the physical address at this page offset the same as + // the physical address we were given? + if (new_paddr != paddr) { + return false; + } + + // Print all the info associated with this page. + message->assign(" (Last Transaction:"); + + if (pe.lastpattern) { + int offset = addr_diff / 8; + datacast_t data; + + data.l32.l = pe.lastpattern->pattern(offset << 1); + data.l32.h = pe.lastpattern->pattern((offset << 1) + 1); + + snprintf(buf, sizeof(buf), " %s data=%#016llx", + pe.lastpattern->name(), data.l64); + message->append(buf); + } + snprintf(buf, sizeof(buf), " tsc=%#llx)", pe.ts); + message->append(buf); + return true; +} + +bool FineLockPEQueue::GetPageFromPhysical(uint64 paddr, + struct page_entry *pe) { + // Traverse through array until finding a page + // that contains the address we want.. + for (int64 i = 0; i < q_size_; i++) { + uint64 page_addr = pages_[i].paddr; + // This assumes linear vaddr. + if ((page_addr <= paddr) && (page_addr + page_size_ > paddr)) { + *pe = pages_[i]; + return true; + } + } + return false; +} + + +// Get a random number from the slot we locked. +uint64 FineLockPEQueue::GetRandom64FromSlot(int slot) { + // 64 bit LCG numbers suggested on the internets by + // http://nuclear.llnl.gov/CNP/rng/rngman/node4.html and others. + uint64 result = 2862933555777941757ULL * rand_seed_[slot] + 3037000493ULL; + rand_seed_[slot] = result; + return result; +} + +// Get a random number, we have 4 generators to choose from so hopefully we +// won't be blocking on this. +uint64 FineLockPEQueue::GetRandom64() { + // Try each available slot. + for (int i = 0; i < 4; i++) { + if (pthread_mutex_trylock(&(randlocks_[i])) == 0) { + uint64 result = GetRandom64FromSlot(i); + pthread_mutex_unlock(&(randlocks_[i])); + return result; + } + } + // Forget it, just wait. + int i = 0; + if (pthread_mutex_lock(&(randlocks_[i])) == 0) { + uint64 result = GetRandom64FromSlot(i); + pthread_mutex_unlock(&(randlocks_[i])); + return result; + } + + logprintf(0, "Process Error: Could not acquire random lock.\n"); + sat_assert(0); + return 0; +} + + +// Helper function to get a random page entry with given predicate, +// ie, page_is_valid() or page_is_empty() as defined in finelock_queue.h. +// +// Setting tag to a value other than kDontCareTag (-1) +// indicates that we need a tag match, otherwise any tag will do. +// +// Returns true on success, false on failure. +bool FineLockPEQueue::GetRandomWithPredicateTag(struct page_entry *pe, + bool (*pred_func)(struct page_entry*), + int32 tag) { + if (!pe || !q_size_) + return false; + + // Randomly index into page entry array. + uint64 first_try = GetRandom64() % q_size_; + uint64 next_try = 1; + + // Traverse through array until finding a page meeting given predicate. + for (int64 i = 0; i < q_size_; i++) { + uint64 index = (next_try + first_try) % q_size_; + // Go through the loop linear conguentially. We are offsetting by + // 'first_try' so this path will be a different sequence for every + // initioal value chosen. + next_try = (a_ * next_try + c_) % (modlength_); + while (next_try >= q_size_) { + // If we have chosen a modlength greater than the queue size, + // discard out of bounds results. + next_try = (a_ * next_try + c_) % (modlength_); + } + + // If page does not meet predicate, don't trylock (expensive). + if (!(pred_func)(&pages_[index])) + continue; + + // If page does not meet tag predicate, don't trylock (expensive). + if ((tag != kDontCareTag) && !(pages_[index].tag & tag)) + continue; + + if (pthread_mutex_trylock(&(pagelocks_[index])) == 0) { + // If page property (valid/empty) changes before successfully locking, + // release page and move on. + if (!(pred_func)(&pages_[index])) { + pthread_mutex_unlock(&(pagelocks_[index])); + continue; + } else { + // A page entry with given predicate is locked, returns success. + *pe = pages_[index]; + + // Add metrics as necessary. + if (pred_func == page_is_valid) { + // Measure time to fetch valid page. + if (queue_metric_ == kTries) + pe->touch = i; + // Measure number of times each page is read. + if (queue_metric_ == kTouch) + pe->touch++; + } + + return true; + } + } + } + + return false; +} + +// Without tag hint. +bool FineLockPEQueue::GetRandomWithPredicate(struct page_entry *pe, + bool (*pred_func)(struct page_entry*)) { + return GetRandomWithPredicateTag(pe, pred_func, kDontCareTag); +} + + +// GetValid() randomly finds a valid page, locks it and returns page entry by +// pointer. +// +// Returns true on success, false on failure. +bool FineLockPEQueue::GetValid(struct page_entry *pe) { + return GetRandomWithPredicate(pe, page_is_valid); +} + +bool FineLockPEQueue::GetValid(struct page_entry *pe, int32 mask) { + return GetRandomWithPredicateTag(pe, page_is_valid, mask); +} + +// GetEmpty() randomly finds an empty page, locks it and returns page entry by +// pointer. +// +// Returns true on success, false on failure. +bool FineLockPEQueue::GetEmpty(struct page_entry *pe, int32 mask) { + return GetRandomWithPredicateTag(pe, page_is_empty, mask); +} +bool FineLockPEQueue::GetEmpty(struct page_entry *pe) { + return GetRandomWithPredicate(pe, page_is_empty); +} + +// PutEmpty puts an empty page back into the queue, making it available by +// releasing the per-page-entry lock. +// +// Returns true on success, false on failure. +bool FineLockPEQueue::PutEmpty(struct page_entry *pe) { + if (!pe || !q_size_) + return false; + + int64 index = pe->offset / page_size_; + if (!valid_index(index)) + return false; + + pages_[index] = *pe; + // Enforce that page entry is indeed empty. + pages_[index].pattern = 0; + return (pthread_mutex_unlock(&(pagelocks_[index])) == 0); +} + +// PutValid puts a valid page back into the queue, making it available by +// releasing the per-page-entry lock. +// +// Returns true on success, false on failure. +bool FineLockPEQueue::PutValid(struct page_entry *pe) { + if (!pe || !page_is_valid(pe) || !q_size_) + return false; + + int64 index = pe->offset / page_size_; + if (!valid_index(index)) + return false; + + pages_[index] = *pe; + return (pthread_mutex_unlock(&(pagelocks_[index])) == 0); +} diff --git a/src/finelock_queue.h b/src/finelock_queue.h new file mode 100644 index 0000000..54b154e --- /dev/null +++ b/src/finelock_queue.h @@ -0,0 +1,116 @@ +// Copyright 2007 Google Inc. All Rights Reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This page entry queue implementation with fine grain locks aim to ease +// lock contention over previous queue implementation (with one lock protecting +// the entire queue). + +#ifndef STRESSAPPTEST_FINELOCK_QUEUE_H_ +#define STRESSAPPTEST_FINELOCK_QUEUE_H_ + +#include + +// This file must work with autoconf on its public version, +// so these includes are correct. +#include "sattypes.h" +#include "pattern.h" +#include "queue.h" // Using page_entry struct. +#include "os.h" + +// This is a threadsafe randomized queue of pages with per-page entry lock +// for worker threads to use. +class FineLockPEQueue { + public: + FineLockPEQueue(uint64 queuesize, int64 pagesize); + ~FineLockPEQueue(); + + // Put and get functions for page entries. + bool GetEmpty(struct page_entry *pe); + bool GetValid(struct page_entry *pe); + bool PutEmpty(struct page_entry *pe); + bool PutValid(struct page_entry *pe); + + // Put and get functions for page entries, selecting on tags. + bool GetEmpty(struct page_entry *pe, int32 tag); + bool GetValid(struct page_entry *pe, int32 tag); + + bool QueueAnalysis(); + bool GetPageFromPhysical(uint64 paddr, struct page_entry *pe); + void set_os(OsLayer *os); + OsLayer::ErrCallback get_err_log_callback(); + bool ErrorLogCallback(uint64 paddr, string *buf); + + private: + // Not that much blocking random number generator. + uint64 GetRandom64(); + uint64 GetRandom64FromSlot(int slot); + + // Helper function to check index range, returns true if index is valid. + bool valid_index(int64 index) { return index >= 0 && index < q_size_; } + + // Returns true if page entry is valid, false otherwise. + static bool page_is_valid(struct page_entry *pe) { + return pe->pattern != NULL; + } + // Returns true if page entry is empty, false otherwise. + static bool page_is_empty(struct page_entry *pe) { + return pe->pattern == NULL; + } + + // Helper function to get a random page entry with given predicate, + // ie, page_is_valid() or page_is_empty() as defined above. + bool GetRandomWithPredicate(struct page_entry *pe, + bool (*pred_func)(struct page_entry*)); + + // Helper function to get a random page entry with given predicate, + // ie, page_is_valid() or page_is_empty() as defined above. + bool GetRandomWithPredicateTag(struct page_entry *pe, + bool (*pred_func)(struct page_entry*), + int32 tag); + + // Used to make a linear congruential path through the queue. + int64 getA(int64 m); + int64 getC(int64 m); + + pthread_mutex_t *pagelocks_; // Per-page-entry locks. + struct page_entry *pages_; // Where page entries are held. + int64 q_size_; // Size of the queue. + int64 page_size_; // For calculating array index from offset. + + enum { + kTries = 1, // Measure the number of attempts in the queue + // before getting a matching page. + kTouch = 2 } // Measure the number of touches on each page. + queue_metric_; // What to measure in the 'tries' field. + + // Progress pseudorandomly through the queue. It's required that we can find + // every value in the list, but progressing through the same order each time + // causes bunching of pages, leading to long seach times for the correct + // type of pages. + int64 a_; // 'a' multiplicative value for progressing + // linear congruentially through the list. + int64 c_; // 'c' additive value for prgressing randomly + // through the list. + int64 modlength_; // 'm' mod value for linear congruential + // generator. Used when q_size_ doesn't + // generate a good progression through the + // list. + + uint64 rand_seed_[4]; // Random number state for 4 generators. + pthread_mutex_t randlocks_[4]; // Per-random-generator locks. + + DISALLOW_COPY_AND_ASSIGN(FineLockPEQueue); +}; + +#endif // STRESSAPPTEST_FINELOCK_QUEUE_H_ diff --git a/src/logger.cc b/src/logger.cc new file mode 100644 index 0000000..81f1e3e --- /dev/null +++ b/src/logger.cc @@ -0,0 +1,151 @@ +// Copyright 2009 Google Inc. All Rights Reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "logger.h" + +#include +#include +#include +#include + +#include +#include + +// This file must work with autoconf on its public version, +// so these includes are correct. +#include "sattypes.h" + + +Logger *Logger::GlobalLogger() { + static Logger logger; + return &logger; +} + +void Logger::VLogF(int priority, const char *format, va_list args) { + if (priority > verbosity_) { + return; + } + char buffer[4096]; + int length = vsnprintf(buffer, sizeof buffer, format, args); + if (length >= sizeof buffer) { + length = sizeof buffer; + buffer[sizeof buffer - 1] = '\n'; + } + QueueLogLine(new string(buffer, length)); +} + +void Logger::StartThread() { + LOGGER_ASSERT(!thread_running_); + thread_running_ = true; + LOGGER_ASSERT(0 == pthread_create(&thread_, NULL, &StartRoutine, this)); +} + +void Logger::StopThread() { + LOGGER_ASSERT(thread_running_); + thread_running_ = false; + LOGGER_ASSERT(0 == pthread_mutex_lock(&queued_lines_mutex_)); + bool need_cond_signal = queued_lines_.empty(); + queued_lines_.push_back(NULL); + LOGGER_ASSERT(0 == pthread_mutex_unlock(&queued_lines_mutex_)); + if (need_cond_signal) { + LOGGER_ASSERT(0 == pthread_cond_signal(&queued_lines_cond_)); + } + LOGGER_ASSERT(0 == pthread_join(thread_, NULL)); +} + +Logger::Logger() : verbosity_(20), log_fd_(-1), thread_running_(false) { + LOGGER_ASSERT(0 == pthread_mutex_init(&queued_lines_mutex_, NULL)); + LOGGER_ASSERT(0 == pthread_cond_init(&queued_lines_cond_, NULL)); + LOGGER_ASSERT(0 == pthread_cond_init(&full_queue_cond_, NULL)); +} + +Logger::~Logger() { + LOGGER_ASSERT(0 == pthread_mutex_destroy(&queued_lines_mutex_)); + LOGGER_ASSERT(0 == pthread_cond_destroy(&queued_lines_cond_)); + LOGGER_ASSERT(0 == pthread_cond_destroy(&full_queue_cond_)); +} + +void Logger::QueueLogLine(string *line) { + LOGGER_ASSERT(line != NULL); + LOGGER_ASSERT(0 == pthread_mutex_lock(&queued_lines_mutex_)); + if (thread_running_) { + if (queued_lines_.size() >= kMaxQueueSize) { + LOGGER_ASSERT(0 == pthread_cond_wait(&full_queue_cond_, + &queued_lines_mutex_)); + } + if (queued_lines_.empty()) { + LOGGER_ASSERT(0 == pthread_cond_signal(&queued_lines_cond_)); + } + queued_lines_.push_back(line); + } else { + WriteAndDeleteLogLine(line); + } + LOGGER_ASSERT(0 == pthread_mutex_unlock(&queued_lines_mutex_)); +} + +namespace { +void WriteToFile(const string& line, int fd) { + LOGGER_ASSERT(write(fd, line.data(), line.size()) == line.size()); +} +} + +void Logger::WriteAndDeleteLogLine(string *line) { + LOGGER_ASSERT(line != NULL); + if (log_fd_ >= 0) { + WriteToFile(*line, log_fd_); + } + WriteToFile(*line, 1); + delete line; +} + +void *Logger::StartRoutine(void *ptr) { + Logger *self = static_cast(ptr); + self->ThreadMain(); + return NULL; +} + +void Logger::ThreadMain() { + vector local_queue; + LOGGER_ASSERT(0 == pthread_mutex_lock(&queued_lines_mutex_)); + + for (;;) { + if (queued_lines_.empty()) { + LOGGER_ASSERT(0 == pthread_cond_wait(&queued_lines_cond_, + &queued_lines_mutex_)); + continue; + } + + // We move the log lines into a local queue so we can release the lock + // while writing them to disk, preventing other threads from blocking on + // our writes. + local_queue.swap(queued_lines_); + if (local_queue.size() >= kMaxQueueSize) { + LOGGER_ASSERT(0 == pthread_cond_broadcast(&full_queue_cond_)); + } + + // Unlock while we process our local queue. + LOGGER_ASSERT(0 == pthread_mutex_unlock(&queued_lines_mutex_)); + for (vector::const_iterator it = local_queue.begin(); + it != local_queue.end(); ++it) { + if (*it == NULL) { + // NULL is guaranteed to be at the end. + return; + } + WriteAndDeleteLogLine(*it); + } + local_queue.clear(); + // We must hold the lock at the start of each iteration of this for loop. + LOGGER_ASSERT(0 == pthread_mutex_lock(&queued_lines_mutex_)); + } +} diff --git a/src/logger.h b/src/logger.h new file mode 100644 index 0000000..3eaea57 --- /dev/null +++ b/src/logger.h @@ -0,0 +1,142 @@ +// Copyright 2009 Google Inc. All Rights Reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef STRESSAPPTEST_LOGGER_H_ +#define STRESSAPPTEST_LOGGER_H_ + +#include +#include + +#include +#include + +// This file must work with autoconf on its public version, +// so these includes are correct. +#include "sattypes.h" + +// Attempts to log additional lines will block when the queue reaches this size. +// Due to how the logging thread works, up to twice this many log lines may be +// outstanding at any point. +static const int kMaxQueueSize = 250; + + +// This is only for use by the Logger class, do not use it elsewhere! +// +// All Logger assertions should use this macro instead of sat_assert(). +// +// This is like sat_assert() from sattypes.h, but whereas sat_assert() tries to +// log the assertion after printing it to stderr, this only prints it to stderr. +// Logging from within the wrong part of the logger would trigger a deadlock, +// and even in places where it wouldn't there's a very good chance that the +// logger is in no condition to handle new log lines. +#define LOGGER_ASSERT(x) \ +{\ + if (!(x)) {\ + fprintf(stderr, "Assertion failed at %s:%d\n", __FILE__, __LINE__);\ + exit(1);\ + }\ +} + + +// This class handles logging in SAT. It is a singleton accessed via +// GlobalLogger(). +// +// By default log lines are written in the calling thread. Call StartThread() +// to launch a dedicated thread for the writes. +class Logger { + public: + // Returns a pointer to the single global Logger instance. Will not return + // NULL. + static Logger *GlobalLogger(); + + // Lines with a priority numerically greater than this will not be logged. + // May not be called while multiple threads are running. + void SetVerbosity(int verbosity) { + verbosity_ = verbosity; + } + + // Sets a file to log to, in addition to stdout. May not be called while + // multiple threads are running. + // + // Args: + // log_fd: The file descriptor to write to. Will not be closed by this + // object. + void SetLogFd(int log_fd) { + LOGGER_ASSERT(log_fd >= 0); + log_fd_ = log_fd; + } + + // Set output to be written to stdout only. This is the default mode. May + // not be called while multiple threads are running. + void SetStdoutOnly() { + log_fd_ = -1; + } + + // Logs a line, with a vprintf(3)-like interface. This will block on writing + // the line to stdout/disk iff the dedicated logging thread is not running. + // This will block on adding the line to the queue if doing so would exceed + // kMaxQueueSize. + // + // Args: + // priority: If this is numerically greater than the verbosity, the line + // will not be logged. + // format: see vprintf(3) + // args: see vprintf(3) + void VLogF(int priority, const char *format, va_list args); + + // Starts the dedicated logging thread. May not be called while multiple + // threads are already running. + void StartThread(); + + // Stops the dedicated logging thread. May only be called when the logging + // thread is the only other thread running. Any queued lines will be logged + // before this returns. Waits for the thread to finish before returning. + void StopThread(); + + private: + Logger(); + + ~Logger(); + + // Args: + // line: Must be non-NULL. This function takes ownership of it. + void QueueLogLine(string *line); + + // Args: + // line: Must be non-NULL. This function takes ownership of it. + void WriteAndDeleteLogLine(string *line); + + // Callback for pthread_create(3). + static void *StartRoutine(void *ptr); + + // Processes the log queue. + void ThreadMain(); + + pthread_t thread_; + int verbosity_; + int log_fd_; + bool thread_running_; + vector queued_lines_; + // This doubles as a mutex for log_fd_ when the logging thread is not running. + pthread_mutex_t queued_lines_mutex_; + // Lets the logging thread know that the queue is no longer empty. + pthread_cond_t queued_lines_cond_; + // Lets the threads blocked on the queue having reached kMaxQueueSize know + // that the queue has been emptied. + pthread_cond_t full_queue_cond_; + + DISALLOW_COPY_AND_ASSIGN(Logger); +}; + +#endif // STRESSAPPTEST_LOGGER_H_ diff --git a/src/main.cc b/src/main.cc new file mode 100644 index 0000000..04cd536 --- /dev/null +++ b/src/main.cc @@ -0,0 +1,56 @@ +// Copyright 2006 Google Inc. All Rights Reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// sat.cc : a stress test for stressful testing + +#include "sattypes.h" +#include "sat.h" + +int main(int argc, char **argv) { + Sat *sat = SatFactory(); + if (sat == NULL) { + logprintf(0, "Process Error: failed to allocate Sat object\n"); + return 255; + } + + if (!sat->ParseArgs(argc, argv)) { + logprintf(0, "Process Error: Sat::ParseArgs() failed\n"); + sat->bad_status(); + } else if (!sat->Initialize()) { + logprintf(0, "Process Error: Sat::Initialize() failed\n"); + sat->bad_status(); + } else if (!sat->Run()) { + logprintf(0, "Process Error: Sat::Run() failed\n"); + sat->bad_status(); + } + sat->PrintResults(); + if (!sat->Cleanup()) { + logprintf(0, "Process Error: Sat::Cleanup() failed\n"); + sat->bad_status(); + } + + int retval; + if (sat->status() != 0) { + logprintf(0, "Process Error: Fatal issue encountered. See above logs for " + "details.\n"); + retval = 1; + } else if (sat->errors() != 0) { + retval = 1; + } else { + retval = 0; + } + + delete sat; + return retval; +} diff --git a/src/os.cc b/src/os.cc new file mode 100644 index 0000000..5c8c8e0 --- /dev/null +++ b/src/os.cc @@ -0,0 +1,642 @@ +// Copyright 2006 Google Inc. All Rights Reserved. +// Author: nsanders +// +// os.cc : os and machine specific implementation +// Copyright 2006 Google Inc. +// for open source release under GPL + +// This file includes an abstracted interface +// for linux-distro specific and HW specific +// interfaces. + +#include "os.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef SHM_HUGETLB +#define SHM_HUGETLB 04000 // remove when glibc defines it +#endif + +#include +#include + +// This file must work with autoconf on its public version, +// so these includes are correct. +#include "sattypes.h" +#include "error_diag.h" + +// OsLayer initialization. +OsLayer::OsLayer() { + testmem_ = 0; + testmemsize_ = 0; + totalmemsize_ = 0; + error_injection_ = false; + normal_mem_ = true; + time_initialized_ = 0; + + regionsize_ = 0; + regioncount_ = 1; + num_cpus_ = 0; + num_nodes_ = 0; + num_cpus_per_node_ = 0; + error_diagnoser_ = 0; + err_log_callback_ = 0; +} + +// OsLayer cleanup. +OsLayer::~OsLayer() { + if (error_diagnoser_) + delete error_diagnoser_; +} + +// OsLayer initialization. +bool OsLayer::Initialize() { + time_initialized_ = time(NULL); + use_hugepages_ = false; + shmid_ = 0; + if (num_cpus_ == 0) { + num_nodes_ = 1; + num_cpus_ = sysconf(_SC_NPROCESSORS_ONLN); + num_cpus_per_node_ = num_cpus_ / num_nodes_; + } + logprintf(5, "Log: %d nodes, %d cpus.\n", num_nodes_, num_cpus_); + sat_assert(CPU_SETSIZE >= num_cpus_); + cpu_sets_.resize(num_nodes_); + cpu_sets_valid_.resize(num_nodes_); + // Create error diagnoser. + error_diagnoser_ = new ErrorDiag(); + if (!error_diagnoser_->set_os(this)) + return false; + return true; +} + +// Machine type detected. Can we implement all these functions correctly? +bool OsLayer::IsSupported() { + // This is the default empty implementation. + // SAT won't really run correctly. + return false; +} + +int OsLayer::AddressMode() { + // Detect 32/64 bit binary. + void *pvoid = 0; + return sizeof(pvoid) * 8; +} + +// Translates user virtual to physical address. +uint64 OsLayer::VirtualToPhysical(void *vaddr) { + // Needs platform specific implementation. + return 0; +} + +// Returns the HD device that contains this file. +string OsLayer::FindFileDevice(string filename) { + return "hdUnknown"; +} + +// Returns a list of locations corresponding to HD devices. +list OsLayer::FindFileDevices() { + // No autodetection on unknown systems. + list locations; + return locations; +} + +// We need to flush the cacheline here. +void OsLayer::Flush(void *vaddr) { + // Use the generic flush. This function is just so we can override + // this if we are so inclined. + FastFlush(vaddr); +} + +// Translate user virtual to physical address. +int OsLayer::FindDimm(uint64 addr, char *buf, int len) { + char tmpbuf[256]; + snprintf(tmpbuf, sizeof(tmpbuf), "DIMM Unknown"); + snprintf(buf, len, "%s", tmpbuf); + return 0; +} + + +// Classifies addresses according to "regions" +// This isn't really implemented meaningfully here.. +int32 OsLayer::FindRegion(uint64 addr) { + static bool warned = false; + + if (regionsize_ == 0) { + regionsize_ = totalmemsize_ / 8; + if (regionsize_ < 512 * kMegabyte) + regionsize_ = 512 * kMegabyte; + regioncount_ = totalmemsize_ / regionsize_; + if (regioncount_ < 1) regioncount_ = 1; + } + + int32 region_num = addr / regionsize_; + if (region_num >= regioncount_) { + if (!warned) { + logprintf(0, "Log: region number %d exceeds region count %d\n", + region_num, regioncount_); + warned = true; + } + region_num = region_num % regioncount_; + } + return region_num; +} + +// Report which cores are associated with a given region. +cpu_set_t *OsLayer::FindCoreMask(int32 region) { + sat_assert(region >= 0); + region %= num_nodes_; + if (!cpu_sets_valid_[region]) { + CPU_ZERO(&cpu_sets_[region]); + for (int i = 0; i < num_cpus_per_node_; ++i) { + CPU_SET(i + region * num_cpus_per_node_, &cpu_sets_[region]); + } + logprintf(5, "Log: Region %d mask 0x%08X\n", + region, cpuset_to_uint32(&cpu_sets_[region])); + cpu_sets_valid_[region] = true; + } + return &cpu_sets_[region]; +} + +// Report an error in an easily parseable way. +bool OsLayer::ErrorReport(const char *part, const char *symptom, int count) { + time_t now = time(NULL); + int ttf = now - time_initialized_; + logprintf(0, "Report Error: %s : %s : %d : %ds\n", symptom, part, count, ttf); + return true; +} + +// Read the number of hugepages out of the kernel interface in proc. +int64 OsLayer::FindHugePages() { + char buf[65] = "0"; + + // This is a kernel interface to query the numebr of hugepages + // available in the system. + static const char *hugepages_info_file = "/proc/sys/vm/nr_hugepages"; + int hpfile = open(hugepages_info_file, O_RDONLY); + + ssize_t bytes_read = read(hpfile, buf, 64); + close(hpfile); + + if (bytes_read <= 0) { + logprintf(12, "Log: /proc/sys/vm/nr_hugepages " + "read did not provide data\n"); + return 0; + } + + if (bytes_read == 64) { + logprintf(0, "Process Error: /proc/sys/vm/nr_hugepages " + "is surprisingly large\n"); + return 0; + } + + // Add a null termintation to be string safe. + buf[bytes_read] = '\0'; + // Read the page count. + int64 pages = strtoull(buf, NULL, 10); // NOLINT + + return pages; +} + +int64 OsLayer::FindFreeMemSize() { + int64 size = 0; + int64 minsize = 0; + if (totalmemsize_ > 0) + return totalmemsize_; + + int64 pages = sysconf(_SC_PHYS_PAGES); + int64 avpages = sysconf(_SC_AVPHYS_PAGES); + int64 pagesize = sysconf(_SC_PAGESIZE); + int64 physsize = pages * pagesize; + int64 avphyssize = avpages * pagesize; + + // Assume 2MB hugepages. + int64 hugepagesize = FindHugePages() * 2 * kMegabyte; + + if ((pages == -1) || (pagesize == -1)) { + logprintf(0, "Process Error: sysconf could not determine memory size.\n"); + return 0; + } + + // We want to leave enough stuff for things to run. + // If more than 2GB is present, leave 192M + 5% for other stuff. + // If less than 2GB is present use 85% of what's available. + // These are fairly arbitrary numbers that seem to work OK. + // + // TODO(nsanders): is there a more correct way to determine target + // memory size? + if (physsize < 2048LL * kMegabyte) + minsize = ((pages * 85) / 100) * pagesize; + else + minsize = ((pages * 95) / 100) * pagesize - (192 * kMegabyte); + + // Use hugepage sizing if available. + if (hugepagesize > 0) { + if (hugepagesize < minsize) { + logprintf(0, "Procedural Error: Not enough hugepages. " + "%lldMB available < %lldMB required.\n", + hugepagesize / kMegabyte, + minsize / kMegabyte); + // Require the calculated minimum amount of memory. + size = minsize; + } else { + // Require that we get all hugepages. + size = hugepagesize; + } + } else { + // Require the calculated minimum amount of memory. + size = minsize; + } + + logprintf(5, "Log: Total %lld MB. Free %lld MB. Hugepages %lld MB. " + "Targeting %lld MB (%lld%%)\n", + physsize / kMegabyte, + avphyssize / kMegabyte, + hugepagesize / kMegabyte, + size / kMegabyte, + size * 100 / physsize); + + totalmemsize_ = size; + return size; +} + +// Allocates all memory available. +int64 OsLayer::AllocateAllMem() { + int64 length = FindFreeMemSize(); + bool retval = AllocateTestMem(length, 0); + if (retval) + return length; + else + return 0; +} + +// Allocate the target memory. This may be from malloc, hugepage pool +// or other platform specific sources. +bool OsLayer::AllocateTestMem(int64 length, uint64 paddr_base) { + // Try hugepages first. + void *buf = 0; + + if (paddr_base) + logprintf(0, "Process Error: non zero paddr_base %#llx is not supported," + " ignore.\n", paddr_base); + + { // Allocate hugepage mapped memory. + int shmid; + void *shmaddr; + + if ((shmid = shmget(2, length, + SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W)) < 0) { + int err = errno; + char errtxt[256] = ""; + strerror_r(err, errtxt, sizeof(errtxt)); + logprintf(12, "Log: failed to allocate shared mem object - err %d (%s)\n", + err, errtxt); + goto hugepage_failover; + } + + shmaddr = shmat(shmid, NULL, NULL); + if (shmaddr == reinterpret_cast(-1)) { + int err = errno; + char errtxt[256] = ""; + shmctl(shmid, IPC_RMID, NULL); + strerror_r(err, errtxt, sizeof(errtxt)); + logprintf(0, "Log: failed to attach shared mem object - err %d (%s).\n", + err, errtxt); + goto hugepage_failover; + } + use_hugepages_ = true; + shmid_ = shmid; + buf = shmaddr; + logprintf(0, "Log: Using hugepages 0x%x at %p.\n", shmid, shmaddr); + } + hugepage_failover: + + + if (!use_hugepages_) { + // Use memalign to ensure that blocks are aligned enough for disk direct IO. + buf = static_cast(memalign(4096, length)); + if (buf) + logprintf(0, "Log: Using memaligned allocation at %p.\n", buf); + else + logprintf(0, "Process Error: memalign returned 0\n"); + } + + testmem_ = buf; + if (buf) { + testmemsize_ = length; + } else { + testmemsize_ = 0; + } + + return (buf != 0); +} + +// Free the test memory. +void OsLayer::FreeTestMem() { + if (testmem_) { + if (use_hugepages_) { + shmdt(testmem_); + shmctl(shmid_, IPC_RMID, NULL); + } else { + free(testmem_); + } + testmem_ = 0; + testmemsize_ = 0; + } +} + + +// Prepare the target memory. It may requre mapping in, or this may be a noop. +void *OsLayer::PrepareTestMem(uint64 offset, uint64 length) { + sat_assert((offset + length) <= testmemsize_); + return reinterpret_cast(reinterpret_cast(testmem_) + offset); +} + +// Release the test memory resources, if any. +void OsLayer::ReleaseTestMem(void *addr, uint64 offset, uint64 length) { +} + +// No error polling on unknown systems. +int OsLayer::ErrorPoll() { + return 0; +} + +// Generally, poll for errors once per second. +void OsLayer::ErrorWait() { + sat_sleep(1); + return; +} + +// Open a PCI bus-dev-func as a file and return its file descriptor. +// Error is indicated by return value less than zero. +int OsLayer::PciOpen(int bus, int device, int function) { + char dev_file[256]; + + snprintf(dev_file, sizeof(dev_file), "/proc/bus/pci/%02x/%02x.%x", + bus, device, function); + + int fd = open(dev_file, O_RDWR); + if (fd == -1) { + logprintf(0, "Process Error: Unable to open PCI bus %d, device %d, " + "function %d (errno %d).\n", + bus, device, function, errno); + return -1; + } + + return fd; +} + + +// Read and write functions to access PCI config. +uint32 OsLayer::PciRead(int fd, uint32 offset, int width) { + // Strict aliasing rules lawyers will cause data corruption + // on cast pointers in some gccs. + union { + uint32 l32; + uint16 l16; + uint8 l8; + } datacast; + datacast.l32 = 0; + uint32 size = width / 8; + + sat_assert((width == 32) || (width == 16) || (width == 8)); + sat_assert(offset <= (256 - size)); + + if (lseek(fd, offset, SEEK_SET) < 0) { + logprintf(0, "Process Error: Can't seek %x\n", offset); + return 0; + } + if (read(fd, &datacast, size) != size) { + logprintf(0, "Process Error: Can't read %x\n", offset); + return 0; + } + + // Extract the data. + switch (width) { + case 8: + sat_assert(&(datacast.l8) == reinterpret_cast(&datacast)); + return datacast.l8; + case 16: + sat_assert(&(datacast.l16) == reinterpret_cast(&datacast)); + return datacast.l16; + case 32: + return datacast.l32; + } + return 0; +} + +void OsLayer::PciWrite(int fd, uint32 offset, uint32 value, int width) { + // Strict aliasing rules lawyers will cause data corruption + // on cast pointers in some gccs. + union { + uint32 l32; + uint16 l16; + uint8 l8; + } datacast; + datacast.l32 = 0; + uint32 size = width / 8; + + sat_assert((width == 32) || (width == 16) || (width == 8)); + sat_assert(offset <= (256 - size)); + + // Cram the data into the right alignment. + switch (width) { + case 8: + sat_assert(&(datacast.l8) == reinterpret_cast(&datacast)); + datacast.l8 = value; + case 16: + sat_assert(&(datacast.l16) == reinterpret_cast(&datacast)); + datacast.l16 = value; + case 32: + datacast.l32 = value; + } + + if (lseek(fd, offset, SEEK_SET) < 0) { + logprintf(0, "Process Error: Can't seek %x\n", offset); + return; + } + if (write(fd, &datacast, size) != size) { + logprintf(0, "Process Error: Can't write %x to %x\n", datacast.l32, offset); + return; + } + + return; +} + + + +// Open dev msr. +int OsLayer::OpenMSR(uint32 core, uint32 address) { + char buf[256]; + snprintf(buf, sizeof(buf), "/dev/cpu/%d/msr", core); + int fd = open(buf, O_RDWR); + if (fd < 0) + return fd; + + uint32 pos = lseek(fd, address, SEEK_SET); + if (pos != address) { + close(fd); + logprintf(5, "Log: can't seek to msr %x, cpu %d\n", address, core); + return -1; + } + + return fd; +} + +bool OsLayer::ReadMSR(uint32 core, uint32 address, uint64 *data) { + int fd = OpenMSR(core, address); + if (fd < 0) + return false; + + // Read from the msr. + bool res = (sizeof(*data) == read(fd, data, sizeof(*data))); + + if (!res) + logprintf(5, "Log: Failed to read msr %x core %d\n", address, core); + + close(fd); + + return res; +} + +bool OsLayer::WriteMSR(uint32 core, uint32 address, uint64 *data) { + int fd = OpenMSR(core, address); + if (fd < 0) + return false; + + // Write to the msr + bool res = (sizeof(*data) == write(fd, data, sizeof(*data))); + + if (!res) + logprintf(5, "Log: Failed to write msr %x core %d\n", address, core); + + close(fd); + + return res; +} + +// Extract bits [n+len-1, n] from a 32 bit word. +// so GetBitField(0x0f00, 8, 4) == 0xf. +uint32 OsLayer::GetBitField(uint32 val, uint32 n, uint32 len) { + return (val >> n) & ((1<d_name[0] == '.') + continue; + + device = new PCIDevice(); + if (sscanf(entry->d_name, "%04x:%02hx:%02x.%d", + &device->domain, &device->bus, &dev, &func) < 4) { + logprintf(0, "Process Error: Couldn't parse %s", entry->d_name); + free(device); + continue; + } + device->dev = dev; + device->func = func; + device->vendor_id = PCIGetValue(entry->d_name, "vendor"); + device->device_id = PCIGetValue(entry->d_name, "device"); + PCIGetResources(entry->d_name, device); + device_list.insert(device_list.end(), device); + } + closedir(dir); + delete buf; + return device_list; +} + +int OsLayer::PCIGetValue(string name, string object) { + int fd, len; + char filename[256]; + char buf[256]; + snprintf(filename, sizeof(filename), "%s/%s/%s", kSysfsPath, + name.c_str(), object.c_str()); + fd = open(filename, O_RDONLY); + if (fd < 0) + return 0; + len = read(fd, buf, 256); + close(fd); + buf[len] = '\0'; + return strtol(buf, NULL, 0); // NOLINT +} + +int OsLayer::PCIGetResources(string name, PCIDevice *device) { + char filename[256]; + char buf[256]; + FILE *file; + int64 start; + int64 end; + int64 size; + int i; + snprintf(filename, sizeof(filename), "%s/%s/%s", kSysfsPath, + name.c_str(), "resource"); + file = fopen(filename, "r"); + if (!file) { + logprintf(0, "Process Error: impossible to find resource file for %s", + filename); + return errno; + } + for (i = 0; i < 6; i++) { + if (!fgets(buf, 256, file)) + break; + sscanf(buf, "%llx %llx", &start, &end); // NOLINT + size = 0; + if (start) + size = end - start + 1; + device->base_addr[i] = start; + device->size[i] = size; + } + fclose(file); + return 0; +} diff --git a/src/os.h b/src/os.h new file mode 100644 index 0000000..6ace58c --- /dev/null +++ b/src/os.h @@ -0,0 +1,265 @@ +// Copyright 2006 Google Inc. All Rights Reserved. +// Author: nsanders, menderico + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef STRESSAPPTEST_OS_H_ // NOLINT +#define STRESSAPPTEST_OS_H_ + +#include +#include +#include +#include +#include + +// This file must work with autoconf on its public version, +// so these includes are correct. +#include "adler32memcpy.h" // NOLINT +#include "sattypes.h" // NOLINT + +const char kSysfsPath[] = "/sys/bus/pci/devices"; + +struct PCIDevice { + int32 domain; + uint16 bus; + uint8 dev; + uint8 func; + uint16 vendor_id; + uint16 device_id; + uint64 base_addr[6]; + uint64 size[6]; +}; + +typedef vector PCIDevices; + +class ErrorDiag; + +// This class implements OS/Platform specific funtions. +class OsLayer { + public: + OsLayer(); + virtual ~OsLayer(); + + // Initializes data strctures and open files. + // Returns false on error. + virtual bool Initialize(); + + // Virtual to physical. This implementation is optional for + // subclasses to implement. + // Takes a pointer, and returns the corresponding bus address. + virtual uint64 VirtualToPhysical(void *vaddr); + + // Prints failed dimm. This implementation is optional for + // subclasses to implement. + // Takes a bus address and string, and prints the DIMM name + // into the string. Returns error status. + virtual int FindDimm(uint64 addr, char *buf, int len); + // Print dimm info, plus more available info. + virtual int FindDimmExtended(uint64 addr, char *buf, int len) { + return FindDimm(addr, buf, len); + } + + + // Classifies addresses according to "regions" + // This may mean different things on different platforms. + virtual int32 FindRegion(uint64 paddr); + // Find cpu cores associated with a region. Either NUMA or arbitrary. + virtual cpu_set_t *FindCoreMask(int32 region); + + // Returns the HD device that contains this file. + virtual string FindFileDevice(string filename); + + // Returns a list of paths coresponding to HD devices found on this machine. + virtual list FindFileDevices(); + + // Polls for errors. This implementation is optional. + // This will poll once for errors and return zero iff no errors were found. + virtual int ErrorPoll(); + + // Delay an appropriate amount of time between polling. + virtual void ErrorWait(); + + // Report errors. This implementation is mandatory. + // This will output a machine readable line regarding the error. + virtual bool ErrorReport(const char *part, const char *symptom, int count); + + // Flushes cacheline. Used to distinguish read or write errors. + // Subclasses may implement this in machine specific ways.. + // Takes a pointer, and flushed the cacheline containing that pointer. + virtual void Flush(void *vaddr); + + // Fast flush, for use in performance critical code. + // This is bound at compile time, and will not pick up + // any runtime machine configuration info. + inline static void FastFlush(void *vaddr) { +#ifdef STRESSAPPTEST_CPU_PPC + asm volatile("dcbf 0,%0; sync" : : "r" (vaddr)); +#else + // Put mfence before and after clflush to make sure: + // 1. The write before the clflush is committed to memory bus; + // 2. The read after the clflush is hitting the memory bus. + // + // From Intel manual: + // CLFLUSH is only ordered by the MFENCE instruction. It is not guaranteed + // to be ordered by any other fencing, serializing or other CLFLUSH + // instruction. For example, software can use an MFENCE instruction to + // insure that previous stores are included in the write-back. + asm volatile("mfence"); + asm volatile("clflush (%0)" :: "r" (vaddr)); + asm volatile("mfence"); +#endif + } + + // Get time in cpu timer ticks. Useful for matching MCEs with software + // actions. + inline static uint64 GetTimestamp(void) { + uint64 tsc; +#ifdef STRESSAPPTEST_CPU_PPC + uint32 tbl, tbu, temp; + __asm __volatile( + "1:\n" + "mftbu %2\n" + "mftb %0\n" + "mftbu %1\n" + "cmpw %2,%1\n" + "bne 1b\n" + : "=r"(tbl), "=r"(tbu), "=r"(temp) + : + : "cc"); + + tsc = (static_cast(tbu) << 32) | static_cast(tbl); +#else + datacast_t data; + __asm __volatile("rdtsc" : "=a" (data.l32.l), "=d"(data.l32.h)); + tsc = data.l64; + +#endif + return (tsc); + } + + // Find the free memory on the machine. + virtual int64 FindFreeMemSize(); + + // Allocates test memory of length bytes. + // Subclasses must implement this. + // Call PepareTestMem to get a pointer. + virtual int64 AllocateAllMem(); // Returns length. + // Returns success. + virtual bool AllocateTestMem(int64 length, uint64 paddr_base); + virtual void FreeTestMem(); + + // Prepares the memory for use. You must call this + // before using test memory, and after you are done. + virtual void *PrepareTestMem(uint64 offset, uint64 length); + virtual void ReleaseTestMem(void *addr, uint64 offset, uint64 length); + + // Machine type detected. Can we implement all these functions correctly? + // Returns true if machine type is detected and implemented. + virtual bool IsSupported(); + + // Returns 32 for 32-bit, 64 for 64-bit. + virtual int AddressMode(); + + // Open, read, write pci cfg through /proc/bus/pci. fd is /proc/pci file. + virtual int PciOpen(int bus, int device, int function); + virtual void PciWrite(int fd, uint32 offset, uint32 value, int width); + virtual uint32 PciRead(int fd, uint32 offset, int width); + + // Read MSRs + virtual bool ReadMSR(uint32 core, uint32 address, uint64 *data); + virtual bool WriteMSR(uint32 core, uint32 address, uint64 *data); + + // Extract bits [n+len-1, n] from a 32 bit word. + // so GetBitField(0x0f00, 8, 4) == 0xf. + virtual uint32 GetBitField(uint32 val, uint32 n, uint32 len); + + // Platform and CPU specific CPU-stressing function. + // Returns true on success, false otherwise. + virtual bool CpuStressWorkload(); + + // Causes false errors for unittesting. + // Setting to "true" causes errors to be injected. + void set_error_injection(bool errors) { error_injection_ = errors; } + bool error_injection() const { return error_injection_; } + + // Is SAT using normal malloc'd memory, or exotic mmap'd memory. + bool normal_mem() const { return normal_mem_; } + + // Get numa config, if available.. + int num_nodes() const { return num_nodes_; } + int num_cpus() const { return num_cpus_; } + + // Handle to platform-specific error diagnoser. + ErrorDiag *error_diagnoser_; + + // Detect all PCI Devices. + virtual PCIDevices GetPCIDevices(); + + // Default platform dependent warm Adler memcpy to C implementation + // for compatibility. + virtual bool AdlerMemcpyWarm(uint64 *dstmem, uint64 *srcmem, + unsigned int size_in_bytes, + AdlerChecksum *checksum) + {return AdlerMemcpyWarmC(dstmem, srcmem, size_in_bytes, checksum);} + + // Store a callback to use to print + // app-specific info about the last error location. + // This call back is called with a physical address, and the app can fill in + // the most recent transaction that occurred at that address. + typedef bool (*ErrCallback)(uint64 paddr, string *buf); + void set_err_log_callback( + ErrCallback err_log_callback) { + err_log_callback_ = err_log_callback; + } + ErrCallback get_err_log_callback() { return err_log_callback_; } + + protected: + void *testmem_; // Location of test memory. + int64 testmemsize_; // Size of test memory. + int64 totalmemsize_; // Size of available memory. + bool error_injection_; // Do error injection? + bool normal_mem_; // Memory DMA capable? + bool use_hugepages_; // Use hugepage shmem? + int shmid_; // Handle to shmem + + int64 regionsize_; // Size of memory "regions" + int regioncount_; // Number of memory "regions" + int num_cpus_; // Number of cpus in the system. + int num_nodes_; // Number of nodes in the system. + int num_cpus_per_node_; // Number of cpus per node in the system. + + time_t time_initialized_; // Start time of test. + + vector cpu_sets_; // Cache for cpu masks. + vector cpu_sets_valid_; // If the cpu mask cache is valid. + + // Get file descriptor for dev msr. + virtual int OpenMSR(uint32 core, uint32 address); + // Auxiliary methods for PCI device configuration + int PCIGetValue(string name, string object); + int PCIGetResources(string name, PCIDevice *device); + + // Look up how many hugepages there are. + virtual int64 FindHugePages(); + + // Link to find last transaction at an error location. + ErrCallback err_log_callback_; + + private: + DISALLOW_COPY_AND_ASSIGN(OsLayer); +}; + +// Selects and returns the proper OS and hardware interface. +OsLayer *OsLayerFactory(const std::map &options); + +#endif // STRESSAPPTEST_OS_H_ NOLINT diff --git a/src/os_factory.cc b/src/os_factory.cc new file mode 100644 index 0000000..8acf573 --- /dev/null +++ b/src/os_factory.cc @@ -0,0 +1,41 @@ +// Copyright 2006 Google Inc. All Rights Reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This file generates an OS interface class consistant with the +// current machine type. No machine type detection is currently done. + +#include +#include +#include +#include + +#include +#include + +#include "os.h" + + +// Select the proper OS and hardware interface. +OsLayer *OsLayerFactory(const std::map &options) { + OsLayer *os = 0; + os = new OsLayer(); + + // Check for memory allocation failure. + if (!os) { + logprintf(0, "Process Error: Can't allocate memory\n"); + return 0; + } + os->Initialize(); + return os; +} diff --git a/src/pattern.cc b/src/pattern.cc new file mode 100644 index 0000000..2fb552a --- /dev/null +++ b/src/pattern.cc @@ -0,0 +1,421 @@ +// Copyright 2006 Google Inc. All Rights Reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// pattern.cc : library of stressful data patterns + +#include + +// This file must work with autoconf on its public version, +// so these includes are correct. +#include "pattern.h" +#include "sattypes.h" + +// Static data patterns. + +static unsigned int walkingOnes_data[] = { + 0x00000001, 0x00000002, 0x00000004, 0x00000008, + 0x00000010, 0x00000020, 0x00000040, 0x00000080, + 0x00000100, 0x00000200, 0x00000400, 0x00000800, + 0x00001000, 0x00002000, 0x00004000, 0x00008000, + 0x00010000, 0x00020000, 0x00040000, 0x00080000, + 0x00100000, 0x00200000, 0x00400000, 0x00800000, + 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x20000000, 0x40000000, 0x80000000, + 0x40000000, 0x20000000, 0x10000000, 0x08000000, + 0x04000000, 0x02000000, 0x01000000, 0x00800000, + 0x00400000, 0x00200000, 0x00100000, 0x00080000, + 0x00040000, 0x00020000, 0x00010000, 0x00008000, + 0x00004000, 0x00002000, 0x00001000, 0x00000800, + 0x00000400, 0x00000200, 0x00000100, 0x00000080, + 0x00000040, 0x00000020, 0x00000010, 0x00000008, + 0x00000004, 0x00000002, 0x00000001, 0x00000000 +}; +static const struct PatternData walkingOnes = { + "walkingOnes", + walkingOnes_data, + (sizeof walkingOnes_data / sizeof walkingOnes_data[0]) - 1, + {1, 1, 2, 1} // Weight for choosing 32/64/128/256 bit wide of this pattern +}; + +static unsigned int walkingInvOnes_data[] = { + 0x00000001, 0xfffffffe, 0x00000002, 0xfffffffd, + 0x00000004, 0xfffffffb, 0x00000008, 0xfffffff7, + 0x00000010, 0xffffffef, 0x00000020, 0xffffffdf, + 0x00000040, 0xffffffbf, 0x00000080, 0xffffff7f, + 0x00000100, 0xfffffeff, 0x00000200, 0xfffffdff, + 0x00000400, 0xfffffbff, 0x00000800, 0xfffff7ff, + 0x00001000, 0xffffefff, 0x00002000, 0xffffdfff, + 0x00004000, 0xffffbfff, 0x00008000, 0xffff7fff, + 0x00010000, 0xfffeffff, 0x00020000, 0xfffdffff, + 0x00040000, 0xfffbffff, 0x00080000, 0xfff7ffff, + 0x00100000, 0xffefffff, 0x00200000, 0xffdfffff, + 0x00400000, 0xffbfffff, 0x00800000, 0xff7fffff, + 0x01000000, 0xfeffffff, 0x02000000, 0xfdffffff, + 0x04000000, 0xfbffffff, 0x08000000, 0xf7ffffff, + 0x10000000, 0xefffffff, 0x20000000, 0xdfffffff, + 0x40000000, 0xbfffffff, 0x80000000, 0x7fffffff, + 0x40000000, 0xbfffffff, 0x20000000, 0xdfffffff, + 0x10000000, 0xefffffff, 0x08000000, 0xf7ffffff, + 0x04000000, 0xfbffffff, 0x02000000, 0xfdffffff, + 0x01000000, 0xfeffffff, 0x00800000, 0xff7fffff, + 0x00400000, 0xffbfffff, 0x00200000, 0xffdfffff, + 0x00100000, 0xffefffff, 0x00080000, 0xfff7ffff, + 0x00040000, 0xfffbffff, 0x00020000, 0xfffdffff, + 0x00010000, 0xfffeffff, 0x00008000, 0xffff7fff, + 0x00004000, 0xffffbfff, 0x00002000, 0xffffdfff, + 0x00001000, 0xffffefff, 0x00000800, 0xfffff7ff, + 0x00000400, 0xfffffbff, 0x00000200, 0xfffffdff, + 0x00000100, 0xfffffeff, 0x00000080, 0xffffff7f, + 0x00000040, 0xffffffbf, 0x00000020, 0xffffffdf, + 0x00000010, 0xffffffef, 0x00000008, 0xfffffff7, + 0x00000004, 0xfffffffb, 0x00000002, 0xfffffffd, + 0x00000001, 0xfffffffe, 0x00000000, 0xffffffff +}; +static const struct PatternData walkingInvOnes = { + "walkingInvOnes", + walkingInvOnes_data, + (sizeof walkingInvOnes_data / sizeof walkingInvOnes_data[0]) - 1, + {2, 2, 5, 5} +}; + +static unsigned int walkingZeros_data[] = { + 0xfffffffe, 0xfffffffd, 0xfffffffb, 0xfffffff7, + 0xffffffef, 0xffffffdf, 0xffffffbf, 0xffffff7f, + 0xfffffeff, 0xfffffdff, 0xfffffbff, 0xfffff7ff, + 0xffffefff, 0xffffdfff, 0xffffbfff, 0xffff7fff, + 0xfffeffff, 0xfffdffff, 0xfffbffff, 0xfff7ffff, + 0xffefffff, 0xffdfffff, 0xffbfffff, 0xff7fffff, + 0xfeffffff, 0xfdffffff, 0xfbffffff, 0xf7ffffff, + 0xefffffff, 0xdfffffff, 0xbfffffff, 0x7fffffff, + 0xbfffffff, 0xdfffffff, 0xefffffff, 0xf7ffffff, + 0xfbffffff, 0xfdffffff, 0xfeffffff, 0xff7fffff, + 0xffbfffff, 0xffdfffff, 0xffefffff, 0xfff7ffff, + 0xfffbffff, 0xfffdffff, 0xfffeffff, 0xffff7fff, + 0xffffbfff, 0xffffdfff, 0xffffefff, 0xfffff7ff, + 0xfffffbff, 0xfffffdff, 0xfffffeff, 0xffffff7f, + 0xffffffbf, 0xffffffdf, 0xffffffef, 0xfffffff7, + 0xfffffffb, 0xfffffffd, 0xfffffffe, 0xffffffff +}; +static const struct PatternData walkingZeros = { + "walkingZeros", + walkingZeros_data, + (sizeof walkingZeros_data / sizeof walkingZeros_data[0]) - 1, + {1, 1, 2, 1} +}; + +static unsigned int OneZero_data[] = { 0x00000000, 0xffffffff}; +static const struct PatternData OneZero = { + "OneZero", + OneZero_data, + (sizeof OneZero_data / sizeof OneZero_data[0]) - 1, + {5, 5, 15, 5} +}; + +static unsigned int JustZero_data[] = { 0x00000000, 0x00000000}; +static const struct PatternData JustZero = { + "JustZero", + JustZero_data, + (sizeof JustZero_data / sizeof JustZero_data[0]) - 1, + {2, 0, 0, 0} +}; + +static unsigned int JustOne_data[] = { 0xffffffff, 0xffffffff}; +static const struct PatternData JustOne = { + "JustOne", + JustOne_data, + (sizeof JustOne_data / sizeof JustOne_data[0]) - 1, + {2, 0, 0, 0} +}; + +static unsigned int JustFive_data[] = { 0x55555555, 0x55555555}; +static const struct PatternData JustFive = { + "JustFive", + JustFive_data, + (sizeof JustFive_data / sizeof JustFive_data[0]) - 1, + {2, 0, 0, 0} +}; + +static unsigned int JustA_data[] = { 0xaaaaaaaa, 0xaaaaaaaa}; +static const struct PatternData JustA = { + "JustA", + JustA_data, + (sizeof JustA_data / sizeof JustA_data[0]) - 1, + {2, 0, 0, 0} +}; + +static unsigned int FiveA_data[] = { 0x55555555, 0xaaaaaaaa}; +static const struct PatternData FiveA = { + "FiveA", + FiveA_data, + (sizeof FiveA_data / sizeof FiveA_data[0]) - 1, + {1, 1, 1, 1} +}; + +static unsigned int FiveA8_data[] = { + 0x5aa5a55a, 0xa55a5aa5, 0xa55a5aa5, 0x5aa5a55a +}; +static const struct PatternData FiveA8 = { + "FiveA8", + FiveA8_data, + (sizeof FiveA8_data / sizeof FiveA8_data[0]) - 1, + {1, 1, 1, 1} +}; + +static unsigned int Long8b10b_data[] = { 0x16161616, 0x16161616 }; +static const struct PatternData Long8b10b = { + "Long8b10b", + Long8b10b_data, + (sizeof Long8b10b_data / sizeof Long8b10b_data[0]) - 1, + {2, 0, 0, 0} +}; + +static unsigned int Short8b10b_data[] = { 0xb5b5b5b5, 0xb5b5b5b5 }; +static const struct PatternData Short8b10b = { + "Short8b10b", + Short8b10b_data, + (sizeof Short8b10b_data / sizeof Short8b10b_data[0]) - 1, + {2, 0, 0, 0} +}; + +static unsigned int Checker8b10b_data[] = { 0xb5b5b5b5, 0x4a4a4a4a }; +static const struct PatternData Checker8b10b = { + "Checker8b10b", + Checker8b10b_data, + (sizeof Checker8b10b_data / sizeof Checker8b10b_data[0]) - 1, + {1, 0, 0, 1} +}; + +static unsigned int Five7_data[] = { 0x55555557, 0x55575555 }; +static const struct PatternData Five7 = { + "Five7", + Five7_data, + (sizeof Five7_data / sizeof Five7_data[0]) - 1, + {0, 2, 0, 0} +}; + +static unsigned int Zero2fd_data[] = { 0x00020002, 0xfffdfffd }; +static const struct PatternData Zero2fd = { + "Zero2fd", + Zero2fd_data, + (sizeof Zero2fd_data / sizeof Zero2fd_data[0]) - 1, + {0, 2, 0, 0} +}; + +// Extern array of useable patterns. +static const struct PatternData pattern_array[] = { + walkingOnes, + walkingInvOnes, + walkingZeros, + OneZero, + JustZero, + JustOne, + JustFive, + JustA, + FiveA, + FiveA8, + Long8b10b, + Short8b10b, + Checker8b10b, + Five7, + Zero2fd, +}; +static const int pattern_array_size = + sizeof pattern_array / sizeof pattern_array[0]; + +Pattern::Pattern() { + crc_ = NULL; +} + +Pattern::~Pattern() { + if (crc_ != NULL) { + delete crc_; + } +} + +// Calculate CRC for this pattern. This must match +// the CRC calculation in worker.cc. +int Pattern::CalculateCrc() { + // TODO(johnhuang): + // Consider refactoring to the form: + // while (i < count) AdlerInc(uint64, uint64, AdlerChecksum*) + uint64 a1 = 1; + uint64 a2 = 1; + uint64 b1 = 0; + uint64 b2 = 0; + + // checksum is calculated using only the first 4096 bytes of data. + int i = 0; + int blocksize = 4096; + int count = blocksize / sizeof i; + while (i < count) { + a1 += pattern(i); + b1 += a1; + i++; + a1 += pattern(i); + b1 += a1; + i++; + + a2 += pattern(i); + b2 += a2; + i++; + a2 += pattern(i); + b2 += a2; + i++; + } + if (crc_ != NULL) { + delete crc_; + } + crc_ = new AdlerChecksum(); + crc_->Set(a1, a2, b1, b2); + return 0; +} + +// Initialize pattern's CRC. +int Pattern::Initialize(const struct PatternData &pattern_init, + int buswidth, + bool invert, + int weight) { + int result = 1; + + pattern_ = &pattern_init; + busshift_ = 2; + inverse_ = invert; + weight_ = weight; + + name_.clear(); + name_.append(pattern_->name); + + if (invert) + name_.append("~"); + + if (buswidth == 32) { + name_.append("32"); + busshift_ = 0; + } else if (buswidth == 64) { + name_.append("64"); + busshift_ = 1; + } else if (buswidth == 128) { + name_.append("128"); + busshift_ = 2; + } else if (buswidth == 256) { + name_.append("256"); + busshift_ = 3; + } else { + logprintf(0, "Process Error: Confused by bus width %d\n", + buswidth); + name_.append("Broken"); + result = 0; + } + + CalculateCrc(); + + return result; +} + + +PatternList::PatternList() { + size_= 0; + initialized_ = 0; +} + +PatternList::~PatternList() { + if (initialized_) { + Destroy(); + } +} + +// Fill in the class with references to the static data patterns +int PatternList::Initialize() { + int patterncount = 0; + int weightcount = 0; + + patterns_.resize(pattern_array_size * 8); + for (int i = 0; i < pattern_array_size; i++) { + // Non inverted. + weightcount += pattern_array[i].weight[0]; + patterns_[patterncount++].Initialize(pattern_array[i], 32, false, + pattern_array[i].weight[0]); + weightcount += pattern_array[i].weight[1]; + patterns_[patterncount++].Initialize(pattern_array[i], 64, false, + pattern_array[i].weight[1]); + weightcount += pattern_array[i].weight[2]; + patterns_[patterncount++].Initialize(pattern_array[i], 128, false, + pattern_array[i].weight[2]); + weightcount += pattern_array[i].weight[3]; + patterns_[patterncount++].Initialize(pattern_array[i], 256, false, + pattern_array[i].weight[3]); + + // Inverted. + weightcount += pattern_array[i].weight[0]; + patterns_[patterncount++].Initialize(pattern_array[i], 32, true, + pattern_array[i].weight[0]); + weightcount += pattern_array[i].weight[1]; + patterns_[patterncount++].Initialize(pattern_array[i], 64, true, + pattern_array[i].weight[1]); + weightcount += pattern_array[i].weight[2]; + patterns_[patterncount++].Initialize(pattern_array[i], 128, true, + pattern_array[i].weight[2]); + weightcount += pattern_array[i].weight[3]; + patterns_[patterncount++].Initialize(pattern_array[i], 256, true, + pattern_array[i].weight[3]); + } + size_ = patterncount; + weightcount_ = weightcount; + initialized_ = 1; + + logprintf(12, "Log: initialized %d data patterns\n", size_); + + return 1; +} + +// Free the stuff. +int PatternList::Destroy() { + if (!initialized_) + return 0; + + patterns_.clear(); + size_ = 0; + initialized_ = 0; + + return 1; +} + +// Return pattern numbered "i" +Pattern *PatternList::GetPattern(int i) { + if (i < size_) { + return &patterns_[i]; + } + + logprintf(0, "Process Error: Out of bounds pattern access\n"); + return 0; +} + +// Return a randomly selected pattern. +Pattern *PatternList::GetRandomPattern() { + unsigned int target = random(); + target = target % weightcount_; + + unsigned int i = 0; + unsigned int sum = 0; + while (target > sum) { + sum += patterns_[i].weight(); + i++; + } + if (i < size_) { + return &patterns_[i]; + } + + logprintf(0, "Process Error: Out of bounds pattern access\n"); + return 0; +} diff --git a/src/pattern.h b/src/pattern.h new file mode 100644 index 0000000..b1168aa --- /dev/null +++ b/src/pattern.h @@ -0,0 +1,124 @@ +// Copyright 2006 Google Inc. All Rights Reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// pattern.h : global pattern references and initialization + +// This file implements easy access to statically declared +// data patterns. + +#ifndef STRESSAPPTEST_PATTERN_H_ +#define STRESSAPPTEST_PATTERN_H_ + +#include +#include + +// This file must work with autoconf on its public version, +// so these includes are correct. +#include "adler32memcpy.h" +#include "sattypes.h" + +// 2 = 128 bit bus, 1 = 64 bit bus, 0 = 32 bit bus +const int kBusShift = 2; + +// Pattern and CRC data structure +struct PatternData { + const char *name; // Name of this pattern. + unsigned int *pat; // Data array. + unsigned int mask; // Size - 1. data[index & mask] is always valid. + unsigned char weight[4]; // Weighted frequency of this pattern. + // Each pattern has 32,64,128,256 width versions. + // All weights are added up, a random number is + // chosen between 0-sum(weights), and the + // appropriate pattern is chosen. Thus a weight of + // 1 is rare, a weight of 10 is 2x as likely to be + // chosen as a weight of 5. +}; + +// Data structure to access data patterns. +class Pattern { + public: + Pattern(); + ~Pattern(); + // Fill pattern data and calculate CRC. + int Initialize(const struct PatternData &pattern_init, + int buswidth, + bool invert, + int weight); + + // Access data members. + // "busshift_" allows for repeating each pattern word 1, 2, 4, etc. times. + // in order to create patterns of different width. + unsigned int pattern(unsigned int offset) { + unsigned int data = pattern_->pat[(offset >> busshift_) & pattern_->mask]; + if (inverse_) + data = ~data; + return data; + } + const AdlerChecksum *crc() {return crc_;} + unsigned int mask() {return pattern_->mask;} + unsigned int weight() {return weight_;} + const char *name() {return name_.c_str();} + + private: + int CalculateCrc(); + const struct PatternData *pattern_; + int busshift_; // Target data bus width. + bool inverse_; // Invert the data from the original pattern. + AdlerChecksum *crc_; // CRC of this pattern. + string name_; // The human readable pattern name. + int weight_; // This is the likelihood that this + // pattern will be chosen. + // We want to copy this! + // DISALLOW_COPY_AND_ASSIGN(Pattern); +}; + +// Object used to access global pattern list. +class PatternList { + public: + PatternList(); + ~PatternList(); + // Initialize pointers to global data patterns, and calculate CRC. + int Initialize(); + int Destroy(); + + // Return the pattern designated by index i. + Pattern *GetPattern(int i); + // Return a random pattern according to the specified weighted probability. + Pattern *GetRandomPattern(); + // Return the number of patterns available. + int Size() {return size_;} + + private: + vector patterns_; + int weightcount_; // Total count of pattern weights. + int size_; + int initialized_; + DISALLOW_COPY_AND_ASSIGN(PatternList); +}; + +// CrcIncrement allows an abstracted way to add a 32bit +// value into a running CRC. This function should be fast, and +// generate meaningful CRCs for the types of data patterns that +// we are using here. +// This CRC formula may not be optimal, but it does work. +// It may be improved in the future. +static inline uint32 CrcIncrement(uint32 crc, uint32 expected, int index) { + uint32 addition = (expected ^ index); + uint32 carry = (addition & crc) >> 31; + + return crc + addition + carry; +} + + +#endif // STRESSAPPTEST_PATTERN_H_ diff --git a/src/queue.cc b/src/queue.cc new file mode 100644 index 0000000..d735e68 --- /dev/null +++ b/src/queue.cc @@ -0,0 +1,118 @@ +// Copyright 2006 Google Inc. All Rights Reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// queue.cc : simple thread safe queue implementation + +#include + +// This file must work with autoconf on its public version, +// so these includes are correct. +#include "queue.h" +#include "sattypes.h" + +// Page entry queue implementation follows. +// Push inserts pages, pop returns a random entry. + + +PageEntryQueue::PageEntryQueue(uint64 queuesize) { + // There must always be one empty queue location, + // since in == out => empty. + q_size_ = queuesize + 1; + pages_ = new struct page_entry[q_size_]; + nextin_ = 0; + nextout_ = 0; + popped_ = 0; + pushed_ = 0; + pthread_mutex_init(&q_mutex_, NULL); +} +PageEntryQueue::~PageEntryQueue() { + delete[] pages_; + pthread_mutex_destroy(&q_mutex_); +} + +// Add a page into this queue. +int PageEntryQueue::Push(struct page_entry *pe) { + int result = 0; + int64 nextnextin; + + if (!pe) + return 0; + + pthread_mutex_lock(&q_mutex_); + nextnextin = (nextin_ + 1) % q_size_; + + if (nextnextin != nextout_) { + pages_[nextin_] = *pe; + + nextin_ = nextnextin; + result = 1; + + pushed_++; + } + + pthread_mutex_unlock(&q_mutex_); + + return result; +} + +// Retrieve a random page from this queue. +int PageEntryQueue::PopRandom(struct page_entry *pe) { + int result = 0; + int64 lastin; + int64 entries; + int64 newindex; + struct page_entry tmp; + + if (!pe) + return 0; + + // TODO(nsanders): we should improve random to get 64 bit randoms, and make + // it more thread friendly. + uint64 rand = random(); + + int retval = pthread_mutex_lock(&q_mutex_); + if (retval) + logprintf(0, "Process Error: pthreads mutex failure %d\n", retval); + + + if (nextin_ != nextout_) { + // Randomized fetch. + // Swap random entry with next out. + { + lastin = (nextin_ - 1 + q_size_) % q_size_; + entries = (lastin - nextout_ + q_size_) % q_size_; + + newindex = nextout_; + if (entries) + newindex = ((rand % entries) + nextout_) % q_size_; + + // Swap the pages. + tmp = pages_[nextout_]; + pages_[nextout_] = pages_[newindex]; + pages_[newindex] = tmp; + } + + // Return next out page. + *pe = pages_[nextout_]; + + nextout_ = (nextout_ + 1) % q_size_; + result = 1; + + popped_++; + } + + pthread_mutex_unlock(&q_mutex_); + + return result; +} diff --git a/src/queue.h b/src/queue.h new file mode 100644 index 0000000..a6296b1 --- /dev/null +++ b/src/queue.h @@ -0,0 +1,85 @@ +// Copyright 2006 Google Inc. All Rights Reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// queue.h : simple queue api + +// This is an interface to a simple thread safe queue, +// used to hold data blocks and patterns. +// The order in which the blocks are returned is random. + +#ifndef STRESSAPPTEST_QUEUE_H_ // NOLINT +#define STRESSAPPTEST_QUEUE_H_ + +#include +#include + +// This file must work with autoconf on its public version, +// so these includes are correct. +#include "sattypes.h" // NOLINT +#include "pattern.h" // NOLINT + +// Tag indicating no preference. +static const int kDontCareTag = -1; +// Tag indicating no preference. +static const int kInvalidTag = 0xf001; + + +// This describes a block of memory, and the expected fill pattern. +struct page_entry { + uint64 offset; + void *addr; + uint64 paddr; + class Pattern *pattern; + int32 tag; // These are tags for use in NUMA affinity or other uses. + uint32 touch; // Counter of the number of reads from this page. + uint64 ts; // Timestamp of the last read from this page. + class Pattern *lastpattern; // Expected Pattern at last read. +}; + +static inline void init_pe(struct page_entry *pe) { + pe->offset = 0; + pe->addr = NULL; + pe->pattern = NULL; + pe->tag = kInvalidTag; + pe->touch = 0; + pe->ts = 0; + pe->lastpattern = NULL; +} + +// This is a threadsafe randomized queue of pages for +// worker threads to use. +class PageEntryQueue { + public: + explicit PageEntryQueue(uint64 queuesize); + ~PageEntryQueue(); + + // Push a page onto the list. + int Push(struct page_entry *pe); + // Pop a random page off of the list. + int PopRandom(struct page_entry *pe); + + private: + struct page_entry *pages_; // Where the pages are held. + int64 nextin_; + int64 nextout_; + int64 q_size_; // Size of the queue. + int64 pushed_; // Number of pages pushed, total. + int64 popped_; // Number of pages popped, total. + pthread_mutex_t q_mutex_; + + DISALLOW_COPY_AND_ASSIGN(PageEntryQueue); +}; + + +#endif // MILES_TESTS_SAT_QUEUE_H_ NOLINT diff --git a/src/sat.cc b/src/sat.cc new file mode 100644 index 0000000..e714ba2 --- /dev/null +++ b/src/sat.cc @@ -0,0 +1,1897 @@ +// Copyright 2006 Google Inc. All Rights Reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// sat.cc : a stress test for stressful testing + +// stressapptest (or SAT, from Stressful Application Test) is a test +// designed to stress the system, as well as provide a comprehensive +// memory interface test. + +// stressapptest can be run using memory only, or using many system components. + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +// #define __USE_GNU +// #define __USE_LARGEFILE64 +#include + +#include +#include + +// This file must work with autoconf on its public version, +// so these includes are correct. +#include "disk_blocks.h" +#include "logger.h" +#include "os.h" +#include "sat.h" +#include "sattypes.h" +#include "worker.h" + +// stressapptest versioning here. +#ifndef PACKAGE_VERSION +static const char* kVersion = "1.0.0"; +#else +static const char* kVersion = PACKAGE_VERSION; +#endif + +// Global stressapptest reference, for use by signal handler. +// This makes Sat objects not safe for multiple instances. +namespace { + Sat *g_sat = NULL; + + // Signal handler for catching break or kill. + // + // This must be installed after g_sat is assigned and while there is a single + // thread. + // + // This must be uninstalled while there is only a single thread, and of course + // before g_sat is cleared or deleted. + void SatHandleBreak(int signal) { + g_sat->Break(); + } +} + +// Opens the logfile for writing if necessary +bool Sat::InitializeLogfile() { + // Open logfile. + if (use_logfile_) { + logfile_ = open(logfilename_, + O_WRONLY | O_CREAT | O_DSYNC, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + if (logfile_ < 0) { + printf("Fatal Error: cannot open file %s for logging\n", + logfilename_); + bad_status(); + return false; + } + // We seek to the end once instead of opening in append mode because no + // other processes should be writing to it while this one exists. + if (lseek(logfile_, 0, SEEK_END) == -1) { + printf("Fatal Error: cannot seek to end of logfile (%s)\n", + logfilename_); + bad_status(); + return false; + } + Logger::GlobalLogger()->SetLogFd(logfile_); + } + return true; +} + +// Check that the environment is known and safe to run on. +// Return 1 if good, 0 if unsuppported. +bool Sat::CheckEnvironment() { + // Check that this is not a debug build. Debug builds lack + // enough performance to stress the system. +#if !defined NDEBUG + if (run_on_anything_) { + logprintf(1, "Log: Running DEBUG version of SAT, " + "with significantly reduced coverage.\n"); + } else { + logprintf(0, "Process Error: Running DEBUG version of SAT, " + "with significantly reduced coverage.\n"); + logprintf(0, "Log: Command line option '-A' bypasses this error.\n"); + bad_status(); + return false; + } +#elif !defined CHECKOPTS + #error Build system regression - COPTS disregarded. +#endif + + // Use all CPUs if nothing is specified. + if (memory_threads_ == -1) { + memory_threads_ = os_->num_cpus(); + logprintf(7, "Log: Defaulting to %d copy threads\n", memory_threads_); + } + + // Use all memory if no size is specified. + if (size_mb_ == 0) + size_mb_ = os_->FindFreeMemSize() / kMegabyte; + size_ = static_cast(size_mb_) * kMegabyte; + + // Autodetect file locations. + if (findfiles_ && (file_threads_ == 0)) { + // Get a space separated sting of disk locations. + list locations = os_->FindFileDevices(); + + // Extract each one. + while (!locations.empty()) { + // Copy and remove the disk name. + string disk = locations.back(); + locations.pop_back(); + + logprintf(12, "Log: disk at %s\n", disk.c_str()); + file_threads_++; + filename_.push_back(disk + "/sat_disk.a"); + file_threads_++; + filename_.push_back(disk + "/sat_disk.b"); + } + } + + // We'd better have some memory by this point. + if (size_ < 1) { + logprintf(0, "Process Error: No memory found to test.\n"); + bad_status(); + return false; + } + + if (tag_mode_ && ((file_threads_ > 0) || + (disk_threads_ > 0) || + (net_threads_ > 0))) { + logprintf(0, "Process Error: Memory tag mode incompatible " + "with disk/network DMA.\n"); + bad_status(); + return false; + } + + if ((address_mode_ == 32) && + (os_->normal_mem()) && + (size_ >= 1499 * kMegabyte)) { + if (run_on_anything_) { + int64 new_size_mb = 1499; + logprintf(1, "Log: 32 bit binary: reducing from %lldMB to %lldMB\n", + size_mb_, + new_size_mb); + size_mb_ = new_size_mb; + size_ = size_mb_ * kMegabyte; + } else { + logprintf(0, "Process Error: %dMB test memory too large " + "for 32 bit binary.\n", + static_cast(size_ / kMegabyte)); + logprintf(0, "Log: Command line option '-A' bypasses this error.\n"); + bad_status(); + return false; + } + } + + // If platform is 32 bit Xeon, floor memory size to multiple of 4. + if (address_mode_ == 32) { + size_mb_ = (size_mb_ / 4) * 4; + size_ = size_mb_ * kMegabyte; + logprintf(1, "Log: Flooring memory allocation to multiple of 4: %lldMB\n", + size_mb_); + } + + // Check if this system is on the whitelist for supported systems. + if (!os_->IsSupported()) { + if (run_on_anything_) { + logprintf(1, "Log: Unsupported system. Running with reduced coverage.\n"); + // This is ok, continue on. + } else { + logprintf(0, "Process Error: Unsupported system, " + "no error reporting available\n"); + logprintf(0, "Log: Command line option '-A' bypasses this error.\n"); + bad_status(); + return false; + } + } + + return true; +} + +// Allocates memory to run the test on +bool Sat::AllocateMemory() { + // Allocate our test memory. + bool result = os_->AllocateTestMem(size_, paddr_base_); + if (!result) { + logprintf(0, "Process Error: failed to allocate memory\n"); + bad_status(); + return false; + } + return true; +} + +// Sets up access to data patterns +bool Sat::InitializePatterns() { + // Initialize pattern data. + patternlist_ = new PatternList(); + if (!patternlist_) { + logprintf(0, "Process Error: failed to allocate patterns\n"); + bad_status(); + return false; + } + if (!patternlist_->Initialize()) { + logprintf(0, "Process Error: failed to initialize patternlist\n"); + bad_status(); + return false; + } + return true; +} + +// Get any valid page, no tag specified. +bool Sat::GetValid(struct page_entry *pe) { + return GetValid(pe, kDontCareTag); +} + + +// Fetch and return empty and full pages into the empty and full pools. +bool Sat::GetValid(struct page_entry *pe, int32 tag) { + bool result = false; + // Get valid page depending on implementation. + if (pe_q_implementation_ == SAT_FINELOCK) + result = finelock_q_->GetValid(pe, tag); + else if (pe_q_implementation_ == SAT_ONELOCK) + result = valid_->PopRandom(pe); + + if (result) { + pe->addr = os_->PrepareTestMem(pe->offset, page_length_); // Map it. + + // Tag this access and current pattern. + pe->ts = os_->GetTimestamp(); + pe->lastpattern = pe->pattern; + + return (pe->addr != 0); // Return success or failure. + } + return false; +} + +bool Sat::PutValid(struct page_entry *pe) { + if (pe->addr != 0) + os_->ReleaseTestMem(pe->addr, pe->offset, page_length_); // Unmap the page. + pe->addr = 0; + + // Put valid page depending on implementation. + if (pe_q_implementation_ == SAT_FINELOCK) + return finelock_q_->PutValid(pe); + else if (pe_q_implementation_ == SAT_ONELOCK) + return valid_->Push(pe); + else + return false; +} + +// Get an empty page with any tag. +bool Sat::GetEmpty(struct page_entry *pe) { + return GetEmpty(pe, kDontCareTag); +} + +bool Sat::GetEmpty(struct page_entry *pe, int32 tag) { + bool result = false; + // Get empty page depending on implementation. + if (pe_q_implementation_ == SAT_FINELOCK) + result = finelock_q_->GetEmpty(pe, tag); + else if (pe_q_implementation_ == SAT_ONELOCK) + result = empty_->PopRandom(pe); + + if (result) { + pe->addr = os_->PrepareTestMem(pe->offset, page_length_); // Map it. + return (pe->addr != 0); // Return success or failure. + } + return false; +} + +bool Sat::PutEmpty(struct page_entry *pe) { + if (pe->addr != 0) + os_->ReleaseTestMem(pe->addr, pe->offset, page_length_); // Unmap the page. + pe->addr = 0; + + // Put empty page depending on implementation. + if (pe_q_implementation_ == SAT_FINELOCK) + return finelock_q_->PutEmpty(pe); + else if (pe_q_implementation_ == SAT_ONELOCK) + return empty_->Push(pe); + else + return false; +} + +// Set up the bitmap of physical pages in case we want to see which pages were +// accessed under this run of SAT. +void Sat::AddrMapInit() { + if (!do_page_map_) + return; + // Find about how much physical mem is in the system. + // TODO(nsanders): Find some way to get the max + // and min phys addr in the system. + uint64 maxsize = os_->FindFreeMemSize() * 4; + sat_assert(maxsize != 0); + + // Make a bitmask of this many pages. Assume that the memory is relatively + // zero based. This is true on x86, typically. + // This is one bit per page. + uint64 arraysize = maxsize / 4096 / 8; + unsigned char *bitmap = new unsigned char[arraysize]; + sat_assert(bitmap); + + // Mark every page as 0, not seen. + memset(bitmap, 0, arraysize); + + page_bitmap_size_ = maxsize; + page_bitmap_ = bitmap; +} + +// Add the 4k pages in this block to the array of pages SAT has seen. +void Sat::AddrMapUpdate(struct page_entry *pe) { + if (!do_page_map_) + return; + + // Go through 4k page blocks. + uint64 arraysize = page_bitmap_size_ / 4096 / 8; + + char *base = reinterpret_cast(pe->addr); + for (int i = 0; i < page_length_; i += 4096) { + uint64 paddr = os_->VirtualToPhysical(base + i); + + int offset = paddr / 4096 / 8; + unsigned char mask = 1 << ((paddr / 4096) % 8); + + if (offset >= arraysize) { + logprintf(0, "Process Error: Physical address %#llx is " + "greater than expected %#llx.\n", + paddr, page_bitmap_size_); + sat_assert(0); + } + page_bitmap_[offset] |= mask; + } +} + +// Print out the physical memory ranges that SAT has accessed. +void Sat::AddrMapPrint() { + if (!do_page_map_) + return; + + uint64 pages = page_bitmap_size_ / 4096; + + uint64 last_page = 0; + bool valid_range = false; + + logprintf(4, "Log: Printing tested physical ranges.\n"); + + for (uint64 i = 0; i < pages; i ++) { + int offset = i / 8; + unsigned char mask = 1 << (i % 8); + + bool touched = page_bitmap_[offset] & mask; + if (touched && !valid_range) { + valid_range = true; + last_page = i * 4096; + } else if (!touched && valid_range) { + valid_range = false; + logprintf(4, "Log: %#016llx - %#016llx\n", last_page, (i * 4096) - 1); + } + } + logprintf(4, "Log: Done printing physical ranges.\n"); +} + +// Initializes page lists and fills pages with data patterns. +bool Sat::InitializePages() { + int result = 1; + // Calculate needed page totals. + int64 neededpages = memory_threads_ + + invert_threads_ + + check_threads_ + + net_threads_ + + file_threads_; + + // Empty-valid page ratio is adjusted depending on queue implementation. + // since fine-grain-locked queue keeps both valid and empty entries in the + // same queue and randomly traverse to find pages, the empty-valid ratio + // should be more even. + if (pe_q_implementation_ == SAT_FINELOCK) + freepages_ = pages_ / 5 * 2; // Mark roughly 2/5 of all pages as Empty. + else + freepages_ = (pages_ / 100) + (2 * neededpages); + + if (freepages_ < neededpages) { + logprintf(0, "Process Error: freepages < neededpages.\n"); + logprintf(1, "Stats: Total: %lld, Needed: %lld, Marked free: %lld\n", + static_cast(pages_), + static_cast(neededpages), + static_cast(freepages_)); + bad_status(); + return false; + } + + if (freepages_ > pages_/2) { + logprintf(0, "Process Error: not enough pages for IO\n"); + logprintf(1, "Stats: Total: %lld, Needed: %lld, Available: %lld\n", + static_cast(pages_), + static_cast(freepages_), + static_cast(pages_/2)); + bad_status(); + return false; + } + logprintf(12, "Log: Allocating pages, Total: %lld Free: %lld\n", + pages_, + freepages_); + + // Initialize page locations. + for (int64 i = 0; i < pages_; i++) { + struct page_entry pe; + init_pe(&pe); + pe.offset = i * page_length_; + result &= PutEmpty(&pe); + } + + if (!result) { + logprintf(0, "Process Error: while initializing empty_ list\n"); + bad_status(); + return false; + } + + // Fill valid pages with test patterns. + // Use fill threads to do this. + WorkerStatus fill_status; + WorkerVector fill_vector; + + logprintf(12, "Starting Fill threads: %d threads, %d pages\n", + fill_threads_, pages_); + // Initialize the fill threads. + for (int i = 0; i < fill_threads_; i++) { + FillThread *thread = new FillThread(); + thread->InitThread(i, this, os_, patternlist_, &fill_status); + if (i != fill_threads_ - 1) { + logprintf(12, "Starting Fill Threads %d: %d pages\n", + i, pages_ / fill_threads_); + thread->SetFillPages(pages_ / fill_threads_); + // The last thread finishes up all the leftover pages. + } else { + logprintf(12, "Starting Fill Threads %d: %d pages\n", + i, pages_ - pages_ / fill_threads_ * i); + thread->SetFillPages(pages_ - pages_ / fill_threads_ * i); + } + fill_vector.push_back(thread); + } + + // Spawn the fill threads. + fill_status.Initialize(); + for (WorkerVector::const_iterator it = fill_vector.begin(); + it != fill_vector.end(); ++it) + (*it)->SpawnThread(); + + // Reap the finished fill threads. + for (WorkerVector::const_iterator it = fill_vector.begin(); + it != fill_vector.end(); ++it) { + (*it)->JoinThread(); + if ((*it)->GetStatus() != 1) { + logprintf(0, "Thread %d failed with status %d at %.2f seconds\n", + (*it)->ThreadID(), (*it)->GetStatus(), + (*it)->GetRunDurationUSec() * 1.0/1000000); + bad_status(); + return false; + } + delete (*it); + } + fill_vector.clear(); + fill_status.Destroy(); + logprintf(12, "Log: Done filling pages.\n"); + logprintf(12, "Log: Allocating pages.\n"); + + AddrMapInit(); + + // Initialize page locations. + for (int64 i = 0; i < pages_; i++) { + struct page_entry pe; + // Only get valid pages with uninitialized tags here. + char buf[256]; + if (GetValid(&pe, kInvalidTag)) { + int64 paddr = os_->VirtualToPhysical(pe.addr); + int32 region = os_->FindRegion(paddr); + + os_->FindDimm(paddr, buf, sizeof(buf)); + if (i < 256) { + logprintf(12, "Log: address: %#llx, %s\n", paddr, buf); + } + region_[region]++; + pe.paddr = paddr; + pe.tag = 1 << region; + region_mask_ |= pe.tag; + + // Generate a physical region map + AddrMapUpdate(&pe); + + // Note: this does not allocate free pages among all regions + // fairly. However, with large enough (thousands) random number + // of pages being marked free in each region, the free pages + // count in each region end up pretty balanced. + if (i < freepages_) { + result &= PutEmpty(&pe); + } else { + result &= PutValid(&pe); + } + } else { + logprintf(0, "Log: didn't tag all pages. %d - %d = %d\n", + pages_, i, pages_ - i); + return false; + } + } + logprintf(12, "Log: Done allocating pages.\n"); + + AddrMapPrint(); + + for (int i = 0; i < 32; i++) { + if (region_mask_ & (1 << i)) { + region_count_++; + logprintf(12, "Log: Region %d: %d.\n", i, region_[i]); + } + } + logprintf(5, "Log: Region mask: 0x%x\n", region_mask_); + + return true; +} + +// Print SAT version info. +bool Sat::PrintVersion() { + logprintf(1, "Stats: SAT revision %s, %d bit binary\n", + kVersion, address_mode_); + logprintf(5, "Log: %s from %s\n", Timestamp(), BuildChangelist()); + + return true; +} + + +// Initializes the resources that SAT needs to run. +// This needs to be called before Run(), and after ParseArgs(). +// Returns true on success, false on error, and will exit() on help message. +bool Sat::Initialize() { + g_sat = this; + + // Initializes sync'd log file to ensure output is saved. + if (!InitializeLogfile()) + return false; + Logger::GlobalLogger()->StartThread(); + + logprintf(5, "Log: Commandline - %s\n", cmdline_.c_str()); + PrintVersion(); + + std::map options; + + GoogleOsOptions(&options); + + // Initialize OS/Hardware interface. + os_ = OsLayerFactory(options); + if (!os_) { + bad_status(); + return false; + } + if (error_injection_) os_->set_error_injection(true); + + // Checks that OS/Build/Platform is supported. + if (!CheckEnvironment()) + return false; + + // Run SAT in monitor only mode, do not continue to allocate resources. + if (monitor_mode_) { + logprintf(5, "Log: Running in monitor-only mode. " + "Will not allocate any memory nor run any stress test. " + "Only polling ECC errors.\n"); + return true; + } + + // Allocate the memory to test. + if (!AllocateMemory()) + return false; + + logprintf(5, "Stats: Starting SAT, %dM, %d seconds\n", + static_cast(size_/kMegabyte), + runtime_seconds_); + + if (!InitializePatterns()) + return false; + + // Initialize memory allocation. + pages_ = size_ / page_length_; + + // Allocate page queue depending on queue implementation switch. + if (pe_q_implementation_ == SAT_FINELOCK) { + finelock_q_ = new FineLockPEQueue(pages_, page_length_); + if (finelock_q_ == NULL) + return false; + finelock_q_->set_os(os_); + os_->set_err_log_callback(finelock_q_->get_err_log_callback()); + } else if (pe_q_implementation_ == SAT_ONELOCK) { + empty_ = new PageEntryQueue(pages_); + valid_ = new PageEntryQueue(pages_); + if ((empty_ == NULL) || (valid_ == NULL)) + return false; + } + + if (!InitializePages()) { + logprintf(0, "Process Error: Initialize Pages failed\n"); + return false; + } + + return true; +} + +// Constructor and destructor. +Sat::Sat() { + // Set defaults, command line might override these. + runtime_seconds_ = 20; + page_length_ = kSatPageSize; + disk_pages_ = kSatDiskPage; + pages_ = 0; + size_mb_ = 0; + size_ = size_mb_ * kMegabyte; + freepages_ = 0; + paddr_base_ = 0; + + user_break_ = false; + verbosity_ = 8; + Logger::GlobalLogger()->SetVerbosity(verbosity_); + strict_ = 1; + warm_ = 0; + run_on_anything_ = 0; + use_logfile_ = 0; + logfile_ = 0; + // Detect 32/64 bit binary. + void *pvoid = 0; + address_mode_ = sizeof(pvoid) * 8; + error_injection_ = false; + crazy_error_injection_ = false; + max_errorcount_ = 0; // Zero means no early exit. + stop_on_error_ = false; + error_poll_ = true; + findfiles_ = false; + + do_page_map_ = false; + page_bitmap_ = 0; + page_bitmap_size_ = 0; + + // Cache coherency data initialization. + cc_test_ = false; // Flag to trigger cc threads. + cc_cacheline_count_ = 2; // Two datastructures of cache line size. + cc_inc_count_ = 1000; // Number of times to increment the shared variable. + cc_cacheline_data_ = 0; // Cache Line size datastructure. + + sat_assert(0 == pthread_mutex_init(&worker_lock_, NULL)); + file_threads_ = 0; + net_threads_ = 0; + listen_threads_ = 0; + // Default to autodetect number of cpus, and run that many threads. + memory_threads_ = -1; + invert_threads_ = 0; + fill_threads_ = 8; + check_threads_ = 0; + cpu_stress_threads_ = 0; + disk_threads_ = 0; + total_threads_ = 0; + + region_mask_ = 0; + region_count_ = 0; + for (int i = 0; i < 32; i++) { + region_[i] = 0; + } + region_mode_ = 0; + + errorcount_ = 0; + statuscount_ = 0; + + valid_ = 0; + empty_ = 0; + finelock_q_ = 0; + // Default to use fine-grain lock for better performance. + pe_q_implementation_ = SAT_FINELOCK; + + os_ = 0; + patternlist_ = 0; + logfilename_[0] = 0; + + read_block_size_ = 512; + write_block_size_ = -1; + segment_size_ = -1; + cache_size_ = -1; + blocks_per_segment_ = -1; + read_threshold_ = -1; + write_threshold_ = -1; + non_destructive_ = 1; + monitor_mode_ = 0; + tag_mode_ = 0; + random_threads_ = 0; + + pause_delay_ = 600; + pause_duration_ = 15; +} + +// Destructor. +Sat::~Sat() { + // We need to have called Cleanup() at this point. + // We should probably enforce this. +} + + +#define ARG_KVALUE(argument, variable, value) \ + if (!strcmp(argv[i], argument)) { \ + variable = value; \ + continue; \ + } + +#define ARG_IVALUE(argument, variable) \ + if (!strcmp(argv[i], argument)) { \ + i++; \ + if (i < argc) \ + variable = strtoull(argv[i], NULL, 0); \ + continue; \ + } + +#define ARG_SVALUE(argument, variable) \ + if (!strcmp(argv[i], argument)) { \ + i++; \ + if (i < argc) \ + snprintf(variable, sizeof(variable), "%s", argv[i]); \ + continue; \ + } + +// Configures SAT from command line arguments. +// This will call exit() given a request for +// self-documentation or unexpected args. +bool Sat::ParseArgs(int argc, char **argv) { + int i; + uint64 filesize = page_length_ * disk_pages_; + + // Parse each argument. + for (i = 1; i < argc; i++) { + // Switch to fall back to corase-grain-lock queue. (for benchmarking) + ARG_KVALUE("--coarse_grain_lock", pe_q_implementation_, SAT_ONELOCK); + + // Set number of megabyte to use. + ARG_IVALUE("-M", size_mb_); + + // Set number of seconds to run. + ARG_IVALUE("-s", runtime_seconds_); + + // Set number of memory copy threads. + ARG_IVALUE("-m", memory_threads_); + + // Set number of memory invert threads. + ARG_IVALUE("-i", invert_threads_); + + // Set number of check-only threads. + ARG_IVALUE("-c", check_threads_); + + // Set number of cache line size datastructures. + ARG_IVALUE("--cc_inc_count", cc_inc_count_); + + // Set number of cache line size datastructures + ARG_IVALUE("--cc_line_count", cc_cacheline_count_); + + // Flag set when cache coherency tests need to be run + ARG_KVALUE("--cc_test", cc_test_, 1); + + // Set number of CPU stress threads. + ARG_IVALUE("-C", cpu_stress_threads_); + + // Set logfile name. + ARG_SVALUE("-l", logfilename_); + + // Verbosity level. + ARG_IVALUE("-v", verbosity_); + + // Set maximum number of errors to collect. Stop running after this many. + ARG_IVALUE("--max_errors", max_errorcount_); + + // Set pattern block size. + ARG_IVALUE("-p", page_length_); + + // Set pattern block size. + ARG_IVALUE("--filesize", filesize); + + // NUMA options. + ARG_KVALUE("--local_numa", region_mode_, kLocalNuma); + ARG_KVALUE("--remote_numa", region_mode_, kRemoteNuma); + + // Autodetect tempfile locations. + ARG_KVALUE("--findfiles", findfiles_, 1); + + // Inject errors to force miscompare code paths + ARG_KVALUE("--force_errors", error_injection_, true); + ARG_KVALUE("--force_errors_like_crazy", crazy_error_injection_, true); + if (crazy_error_injection_) + error_injection_ = true; + + // Stop immediately on any arror, for debugging HW problems. + ARG_KVALUE("--stop_on_errors", stop_on_error_, 1); + + // Don't use internal error polling, allow external detection. + ARG_KVALUE("--no_errors", error_poll_, 0); + + // Never check data as you go. + ARG_KVALUE("-F", strict_, 0); + + // Warm the cpu as you go. + ARG_KVALUE("-W", warm_, 1); + + // Allow runnign on unknown systems with base unimplemented OsLayer + ARG_KVALUE("-A", run_on_anything_, 1); + + // Size of read blocks for disk test. + ARG_IVALUE("--read-block-size", read_block_size_); + + // Size of write blocks for disk test. + ARG_IVALUE("--write-block-size", write_block_size_); + + // Size of segment for disk test. + ARG_IVALUE("--segment-size", segment_size_); + + // Size of disk cache size for disk test. + ARG_IVALUE("--cache-size", cache_size_); + + // Number of blocks to test per segment. + ARG_IVALUE("--blocks-per-segment", blocks_per_segment_); + + // Maximum time a block read should take before warning. + ARG_IVALUE("--read-threshold", read_threshold_); + + // Maximum time a block write should take before warning. + ARG_IVALUE("--write-threshold", write_threshold_); + + // Do not write anything to disk in the disk test. + ARG_KVALUE("--destructive", non_destructive_, 0); + + // Run SAT in monitor mode. No test load at all. + ARG_KVALUE("--monitor_mode", monitor_mode_, true); + + // Run SAT in address mode. Tag all cachelines by virt addr. + ARG_KVALUE("--tag_mode", tag_mode_, true); + + // Dump range map of tested pages.. + ARG_KVALUE("--do_page_map", do_page_map_, true); + + // Specify the physical address base to test. + ARG_IVALUE("--paddr_base", paddr_base_); + + // Specify the frequency for power spikes. + ARG_IVALUE("--pause_delay", pause_delay_); + + // Specify the duration of each pause (for power spikes). + ARG_IVALUE("--pause_duration", pause_duration_); + + // Disk device names + if (!strcmp(argv[i], "-d")) { + i++; + if (i < argc) { + disk_threads_++; + diskfilename_.push_back(string(argv[i])); + blocktables_.push_back(new DiskBlockTable()); + } + continue; + } + + // Set number of disk random threads for each disk write thread. + ARG_IVALUE("--random-threads", random_threads_); + + // Set a tempfile to use in a file thread. + if (!strcmp(argv[i], "-f")) { + i++; + if (i < argc) { + file_threads_++; + filename_.push_back(string(argv[i])); + } + continue; + } + + // Set a hostname to use in a network thread. + if (!strcmp(argv[i], "-n")) { + i++; + if (i < argc) { + net_threads_++; + ipaddrs_.push_back(string(argv[i])); + } + continue; + } + + // Run threads that listen for incoming SAT net connections. + ARG_KVALUE("--listen", listen_threads_, 1); + + if (CheckGoogleSpecificArgs(argc, argv, &i)) { + continue; + } + + // Default: + PrintVersion(); + PrintHelp(); + if (strcmp(argv[i], "-h") && strcmp(argv[i], "--help")) { + printf("\n Unknown argument %s\n", argv[i]); + bad_status(); + exit(1); + } + // Forget it, we printed the help, just bail. + // We don't want to print test status, or any log parser stuff. + exit(0); + } + + Logger::GlobalLogger()->SetVerbosity(verbosity_); + + // Update relevant data members with parsed input. + // Translate MB into bytes. + size_ = static_cast(size_mb_) * kMegabyte; + + // Set logfile flag. + if (strcmp(logfilename_, "")) + use_logfile_ = 1; + // Checks valid page length. + if (page_length_ && + !(page_length_ & (page_length_ - 1)) && + (page_length_ > 1023)) { + // Prints if we have changed from default. + if (page_length_ != kSatPageSize) + logprintf(12, "Log: Updating page size to %d\n", page_length_); + } else { + // Revert to default page length. + logprintf(6, "Process Error: " + "Invalid page size %d\n", page_length_); + page_length_ = kSatPageSize; + return false; + } + + // Set disk_pages_ if filesize or page size changed. + if (filesize != page_length_ * disk_pages_) { + disk_pages_ = filesize / page_length_; + if (disk_pages_ == 0) + disk_pages_ = 1; + } + + // Print each argument. + for (int i = 0; i < argc; i++) { + if (i) + cmdline_ += " "; + cmdline_ += argv[i]; + } + + return true; +} + +void Sat::PrintHelp() { + printf("Usage: ./sat(32|64) [options]\n" + " -M mbytes megabytes of ram to test\n" + " -s seconds number of seconds to run\n" + " -m threads number of memory copy threads to run\n" + " -i threads number of memory invert threads to run\n" + " -C threads number of memory CPU stress threads to run\n" + " --findfiles find locations to do disk IO automatically\n" + " -d device add a direct write disk thread with block " + "device (or file) 'device'\n" + " -f filename add a disk thread with " + "tempfile 'filename'\n" + " -l logfile log output to file 'logfile'\n" + " --max_errors n exit early after finding 'n' errors\n" + " -v level verbosity (0-20), default is 8\n" + " -W Use more CPU-stressful memory copy\n" + " -A run in degraded mode on incompatible systems\n" + " -p pagesize size in bytes of memory chunks\n" + " --filesize size size of disk IO tempfiles\n" + " -n ipaddr add a network thread connecting to " + "system at 'ipaddr'\n" + " --listen run a thread to listen for and respond " + "to network threads.\n" + " --no_errors run without checking for ECC or other errors\n" + " --force_errors inject false errors to test error handling\n" + " --force_errors_like_crazy inject a lot of false errors " + "to test error handling\n" + " -F don't result check each transaction\n" + "--stop_on_errors Stop after finding the first error.\n" + " --read-block-size size of block for reading (-d)\n" + " --write-block-size size of block for writing (-d). If not " + "defined, the size of block for writing will be defined as the " + "size of block for reading\n" + " --segment-size size of segments to split disk into (-d)\n" + " --cache-size size of disk cache (-d)\n" + " --blocks-per-segment number of blocks to read/write per " + "segment per iteration (-d)\n" + " --read-threshold maximum time (in us) a block read should " + "take (-d)\n" + " --write-threshold maximum time (in us) a block write " + "should take (-d)\n" + " --random-threads number of random threads for each disk " + "write thread (-d)\n" + " --destructive write/wipe disk partition (-d)\n" + " --monitor_mode only do ECC error polling, no stress load.\n" + " --cc_test do the cache coherency testing\n" + " --cc_inc_count number of times to increment the " + "cacheline's member\n" + " --cc_line_count number of cache line sized datastructures " + "to allocate for the cache coherency threads to operate\n" + " --paddr_base allocate memory starting from this address\n" + " --pause_delay delay (in seconds) between power spikes\n" + " --pause_duration duration (in seconds) of each pause\n" + " --local_numa : choose memory regions associated with " + "each CPU to be tested by that CPU\n" + "--remote_numa : choose memory regions not associated with " + "each CPU to be tested by that CPU\n"); +} + +bool Sat::CheckGoogleSpecificArgs(int argc, char **argv, int *i) { + // Do nothing, no google-specific argument on public stressapptest + return false; +} + +void Sat::GoogleOsOptions(std::map *options) { + // Do nothing, no OS-specific argument on public stressapptest +} + +namespace { + // This counts the bits set in a bitmask. + // This is used to determine number of cores in an available mask. + int countbits(uint32 bitfield) { + int numbits = 0; + for (int i = 0; i < 32; i++) { + if (bitfield & (1 << i)) { + numbits++; + } + } + return numbits; + } +} + +// Launch the SAT task threads. Returns 0 on error. +void Sat::InitializeThreads() { + // Memory copy threads. + AcquireWorkerLock(); + + logprintf(12, "Log: Starting worker threads\n"); + WorkerVector *memory_vector = new WorkerVector(); + + // Error polling thread. + // This may detect ECC corrected errors, disk problems, or + // any other errors normally hidden from userspace. + WorkerVector *error_vector = new WorkerVector(); + if (error_poll_) { + ErrorPollThread *thread = new ErrorPollThread(); + thread->InitThread(total_threads_++, this, os_, patternlist_, + &continuous_status_); + + error_vector->insert(error_vector->end(), thread); + } else { + logprintf(5, "Log: Skipping error poll thread due to --no_errors flag\n"); + } + workers_map_.insert(make_pair(kErrorType, error_vector)); + + // Only start error poll threads for monitor-mode SAT, + // skip all other types of worker threads. + if (monitor_mode_) { + ReleaseWorkerLock(); + return; + } + + for (int i = 0; i < memory_threads_; i++) { + CopyThread *thread = new CopyThread(); + thread->InitThread(total_threads_++, this, os_, patternlist_, + &power_spike_status_); + + if ((region_count_ > 1) && (region_mode_)) { + int32 region = region_find(i % region_count_); + cpu_set_t *cpuset = os_->FindCoreMask(region); + sat_assert(cpuset); + int32 cpu_mask = cpuset_to_uint32(cpuset); + if (region_mode_ == kLocalNuma) { + // Choose regions associated with this CPU. + thread->set_cpu_mask(cpu_mask); + thread->set_tag(1 << region); + } else if (region_mode_ == kRemoteNuma) { + // Choose regions not associated with this CPU.. + thread->set_cpu_mask(cpu_mask); + thread->set_tag(region_mask_ & ~(1 << region)); + } + } else { + int cores = countbits(thread->AvailableCpus()); + // Don't restrict thread location if we have more than one + // thread per core. Not so good for performance. + if (cpu_stress_threads_ + memory_threads_ <= cores) { + // Place a thread on alternating cores first. + // This assures interleaved core use with no overlap. + int nthcore = i; + int nthbit = (((2 * nthcore) % cores) + + (((2 * nthcore) / cores) % 2)) % cores; + if (thread->AvailableCpus() != ((1 << cores) - 1)) { + // We are assuming the bits are contiguous. + // Complain if this is not so. + logprintf(0, "Log: cores = %x, expected %x\n", + thread->AvailableCpus(), ((1 << (cores + 1)) - 1)); + } + + // Set thread affinity. + thread->set_cpu_mask(1 << nthbit); + } + } + memory_vector->insert(memory_vector->end(), thread); + } + workers_map_.insert(make_pair(kMemoryType, memory_vector)); + + // File IO threads. + WorkerVector *fileio_vector = new WorkerVector(); + for (int i = 0; i < file_threads_; i++) { + FileThread *thread = new FileThread(); + thread->InitThread(total_threads_++, this, os_, patternlist_, + &power_spike_status_); + thread->SetFile(filename_[i].c_str()); + // Set disk threads high priority. They don't take much processor time, + // but blocking them will delay disk IO. + thread->SetPriority(WorkerThread::High); + + fileio_vector->insert(fileio_vector->end(), thread); + } + workers_map_.insert(make_pair(kFileIOType, fileio_vector)); + + // Net IO threads. + WorkerVector *netio_vector = new WorkerVector(); + WorkerVector *netslave_vector = new WorkerVector(); + if (listen_threads_ > 0) { + // Create a network slave thread. This listens for connections. + NetworkListenThread *thread = new NetworkListenThread(); + thread->InitThread(total_threads_++, this, os_, patternlist_, + &continuous_status_); + + netslave_vector->insert(netslave_vector->end(), thread); + } + for (int i = 0; i < net_threads_; i++) { + NetworkThread *thread = new NetworkThread(); + thread->InitThread(total_threads_++, this, os_, patternlist_, + &continuous_status_); + thread->SetIP(ipaddrs_[i].c_str()); + + netio_vector->insert(netio_vector->end(), thread); + } + workers_map_.insert(make_pair(kNetIOType, netio_vector)); + workers_map_.insert(make_pair(kNetSlaveType, netslave_vector)); + + // Result check threads. + WorkerVector *check_vector = new WorkerVector(); + for (int i = 0; i < check_threads_; i++) { + CheckThread *thread = new CheckThread(); + thread->InitThread(total_threads_++, this, os_, patternlist_, + &continuous_status_); + + check_vector->insert(check_vector->end(), thread); + } + workers_map_.insert(make_pair(kCheckType, check_vector)); + + // Memory invert threads. + logprintf(12, "Log: Starting invert threads\n"); + WorkerVector *invert_vector = new WorkerVector(); + for (int i = 0; i < invert_threads_; i++) { + InvertThread *thread = new InvertThread(); + thread->InitThread(total_threads_++, this, os_, patternlist_, + &continuous_status_); + + invert_vector->insert(invert_vector->end(), thread); + } + workers_map_.insert(make_pair(kInvertType, invert_vector)); + + // Disk stress threads. + WorkerVector *disk_vector = new WorkerVector(); + WorkerVector *random_vector = new WorkerVector(); + logprintf(12, "Log: Starting disk stress threads\n"); + for (int i = 0; i < disk_threads_; i++) { + // Creating write threads + DiskThread *thread = new DiskThread(blocktables_[i]); + thread->InitThread(total_threads_++, this, os_, patternlist_, + &power_spike_status_); + thread->SetDevice(diskfilename_[i].c_str()); + if (thread->SetParameters(read_block_size_, write_block_size_, + segment_size_, cache_size_, + blocks_per_segment_, + read_threshold_, write_threshold_, + non_destructive_)) { + disk_vector->insert(disk_vector->end(), thread); + } else { + logprintf(12, "Log: DiskThread::SetParameters() failed\n"); + delete thread; + } + + for (int j = 0; j < random_threads_; j++) { + // Creating random threads + RandomDiskThread *rthread = new RandomDiskThread(blocktables_[i]); + rthread->InitThread(total_threads_++, this, os_, patternlist_, + &power_spike_status_); + rthread->SetDevice(diskfilename_[i].c_str()); + if (rthread->SetParameters(read_block_size_, write_block_size_, + segment_size_, cache_size_, + blocks_per_segment_, + read_threshold_, write_threshold_, + non_destructive_)) { + random_vector->insert(random_vector->end(), rthread); + } else { + logprintf(12, "Log: RandomDiskThread::SetParameters() failed\n"); + delete rthread; + } + } + } + + workers_map_.insert(make_pair(kDiskType, disk_vector)); + workers_map_.insert(make_pair(kRandomDiskType, random_vector)); + + // CPU stress threads. + WorkerVector *cpu_vector = new WorkerVector(); + logprintf(12, "Log: Starting cpu stress threads\n"); + for (int i = 0; i < cpu_stress_threads_; i++) { + CpuStressThread *thread = new CpuStressThread(); + thread->InitThread(total_threads_++, this, os_, patternlist_, + &continuous_status_); + + // Don't restrict thread location if we have more than one + // thread per core. Not so good for performance. + int cores = countbits(thread->AvailableCpus()); + if (cpu_stress_threads_ + memory_threads_ <= cores) { + // Place a thread on alternating cores first. + // Go in reverse order for CPU stress threads. This assures interleaved + // core use with no overlap. + int nthcore = (cores - 1) - i; + int nthbit = (((2 * nthcore) % cores) + + (((2 * nthcore) / cores) % 2)) % cores; + if (thread->AvailableCpus() != ((1 << cores) - 1)) { + logprintf(0, "Log: cores = %x, expected %x\n", + thread->AvailableCpus(), ((1 << (cores + 1)) - 1)); + } + + // Set thread affinity. + thread->set_cpu_mask(1 << nthbit); + } + + + cpu_vector->insert(cpu_vector->end(), thread); + } + workers_map_.insert(make_pair(kCPUType, cpu_vector)); + + // CPU Cache Coherency Threads - one for each core available. + if (cc_test_) { + WorkerVector *cc_vector = new WorkerVector(); + logprintf(12, "Log: Starting cpu cache coherency threads\n"); + + // Allocate the shared datastructure to be worked on by the threads. + cc_cacheline_data_ = reinterpret_cast( + malloc(sizeof(cc_cacheline_data) * cc_cacheline_count_)); + sat_assert(cc_cacheline_data_ != NULL); + + // Initialize the strucutre. + memset(cc_cacheline_data_, 0, + sizeof(cc_cacheline_data) * cc_cacheline_count_); + + int num_cpus = CpuCount(); + // Allocate all the nums once so that we get a single chunk + // of contiguous memory. + int *num; + int err_result = posix_memalign( + reinterpret_cast(&num), + kCacheLineSize, sizeof(*num) * num_cpus * cc_cacheline_count_); + sat_assert(err_result == 0); + + int cline; + for (cline = 0; cline < cc_cacheline_count_; cline++) { + memset(num, 0, sizeof(num_cpus) * num_cpus); + cc_cacheline_data_[cline].num = num; + num += num_cpus; + } + + int tnum; + for (tnum = 0; tnum < num_cpus; tnum++) { + CpuCacheCoherencyThread *thread = + new CpuCacheCoherencyThread(cc_cacheline_data_, cc_cacheline_count_, + tnum, cc_inc_count_); + thread->InitThread(total_threads_++, this, os_, patternlist_, + &continuous_status_); + // Pin the thread to a particular core. + thread->set_cpu_mask(1 << tnum); + + // Insert the thread into the vector. + cc_vector->insert(cc_vector->end(), thread); + } + workers_map_.insert(make_pair(kCCType, cc_vector)); + } + ReleaseWorkerLock(); +} + +// Return the number of cpus actually present in the machine. +int Sat::CpuCount() { + return sysconf(_SC_NPROCESSORS_CONF); +} + +// Notify and reap worker threads. +void Sat::JoinThreads() { + logprintf(12, "Log: Joining worker threads\n"); + power_spike_status_.StopWorkers(); + continuous_status_.StopWorkers(); + + AcquireWorkerLock(); + for (WorkerMap::const_iterator map_it = workers_map_.begin(); + map_it != workers_map_.end(); ++map_it) { + for (WorkerVector::const_iterator it = map_it->second->begin(); + it != map_it->second->end(); ++it) { + logprintf(12, "Log: Joining thread %d\n", (*it)->ThreadID()); + (*it)->JoinThread(); + } + } + ReleaseWorkerLock(); + + QueueStats(); + + // Finish up result checking. + // Spawn 4 check threads to minimize check time. + logprintf(12, "Log: Finished countdown, begin to result check\n"); + WorkerStatus reap_check_status; + WorkerVector reap_check_vector; + + // No need for check threads for monitor mode. + if (!monitor_mode_) { + // Initialize the check threads. + for (int i = 0; i < fill_threads_; i++) { + CheckThread *thread = new CheckThread(); + thread->InitThread(total_threads_++, this, os_, patternlist_, + &reap_check_status); + logprintf(12, "Log: Finished countdown, begin to result check\n"); + reap_check_vector.push_back(thread); + } + } + + reap_check_status.Initialize(); + // Check threads should be marked to stop ASAP. + reap_check_status.StopWorkers(); + + // Spawn the check threads. + for (WorkerVector::const_iterator it = reap_check_vector.begin(); + it != reap_check_vector.end(); ++it) { + logprintf(12, "Log: Spawning thread %d\n", (*it)->ThreadID()); + (*it)->SpawnThread(); + } + + // Join the check threads. + for (WorkerVector::const_iterator it = reap_check_vector.begin(); + it != reap_check_vector.end(); ++it) { + logprintf(12, "Log: Joining thread %d\n", (*it)->ThreadID()); + (*it)->JoinThread(); + } + + // Reap all children. Stopped threads should have already ended. + // Result checking threads will end when they have finished + // result checking. + logprintf(12, "Log: Join all outstanding threads\n"); + + // Find all errors. + errorcount_ = GetTotalErrorCount(); + + AcquireWorkerLock(); + for (WorkerMap::const_iterator map_it = workers_map_.begin(); + map_it != workers_map_.end(); ++map_it) { + for (WorkerVector::const_iterator it = map_it->second->begin(); + it != map_it->second->end(); ++it) { + logprintf(12, "Log: Reaping thread status %d\n", (*it)->ThreadID()); + if ((*it)->GetStatus() != 1) { + logprintf(0, "Process Error: Thread %d failed with status %d at " + "%.2f seconds\n", + (*it)->ThreadID(), (*it)->GetStatus(), + (*it)->GetRunDurationUSec()*1.0/1000000); + bad_status(); + } + int priority = 12; + if ((*it)->GetErrorCount()) + priority = 5; + logprintf(priority, "Log: Thread %d found %lld hardware incidents\n", + (*it)->ThreadID(), (*it)->GetErrorCount()); + } + } + ReleaseWorkerLock(); + + + // Add in any errors from check threads. + for (WorkerVector::const_iterator it = reap_check_vector.begin(); + it != reap_check_vector.end(); ++it) { + logprintf(12, "Log: Reaping thread status %d\n", (*it)->ThreadID()); + if ((*it)->GetStatus() != 1) { + logprintf(0, "Process Error: Thread %d failed with status %d at " + "%.2f seconds\n", + (*it)->ThreadID(), (*it)->GetStatus(), + (*it)->GetRunDurationUSec()*1.0/1000000); + bad_status(); + } + errorcount_ += (*it)->GetErrorCount(); + int priority = 12; + if ((*it)->GetErrorCount()) + priority = 5; + logprintf(priority, "Log: Thread %d found %lld hardware incidents\n", + (*it)->ThreadID(), (*it)->GetErrorCount()); + delete (*it); + } + reap_check_vector.clear(); + reap_check_status.Destroy(); +} + +// Print queuing information. +void Sat::QueueStats() { + finelock_q_->QueueAnalysis(); +} + +void Sat::AnalysisAllStats() { + float max_runtime_sec = 0.; + float total_data = 0.; + float total_bandwidth = 0.; + float thread_runtime_sec = 0.; + + for (WorkerMap::const_iterator map_it = workers_map_.begin(); + map_it != workers_map_.end(); ++map_it) { + for (WorkerVector::const_iterator it = map_it->second->begin(); + it != map_it->second->end(); ++it) { + thread_runtime_sec = (*it)->GetRunDurationUSec()*1.0/1000000; + total_data += (*it)->GetMemoryCopiedData(); + total_data += (*it)->GetDeviceCopiedData(); + if (thread_runtime_sec > max_runtime_sec) { + max_runtime_sec = thread_runtime_sec; + } + } + } + + total_bandwidth = total_data / max_runtime_sec; + + logprintf(0, "Stats: Completed: %.2fM in %.2fs %.2fMB/s, " + "with %d hardware incidents, %d errors\n", + total_data, + max_runtime_sec, + total_bandwidth, + errorcount_, + statuscount_); +} + +void Sat::MemoryStats() { + float memcopy_data = 0.; + float memcopy_bandwidth = 0.; + WorkerMap::const_iterator mem_it = workers_map_.find( + static_cast(kMemoryType)); + WorkerMap::const_iterator file_it = workers_map_.find( + static_cast(kFileIOType)); + sat_assert(mem_it != workers_map_.end()); + sat_assert(file_it != workers_map_.end()); + for (WorkerVector::const_iterator it = mem_it->second->begin(); + it != mem_it->second->end(); ++it) { + memcopy_data += (*it)->GetMemoryCopiedData(); + memcopy_bandwidth += (*it)->GetMemoryBandwidth(); + } + for (WorkerVector::const_iterator it = file_it->second->begin(); + it != file_it->second->end(); ++it) { + memcopy_data += (*it)->GetMemoryCopiedData(); + memcopy_bandwidth += (*it)->GetMemoryBandwidth(); + } + GoogleMemoryStats(&memcopy_data, &memcopy_bandwidth); + logprintf(4, "Stats: Memory Copy: %.2fM at %.2fMB/s\n", + memcopy_data, + memcopy_bandwidth); +} + +void Sat::GoogleMemoryStats(float *memcopy_data, + float *memcopy_bandwidth) { + // Do nothing, should be implemented by subclasses. +} + +void Sat::FileStats() { + float file_data = 0.; + float file_bandwidth = 0.; + WorkerMap::const_iterator file_it = workers_map_.find( + static_cast(kFileIOType)); + sat_assert(file_it != workers_map_.end()); + for (WorkerVector::const_iterator it = file_it->second->begin(); + it != file_it->second->end(); ++it) { + file_data += (*it)->GetDeviceCopiedData(); + file_bandwidth += (*it)->GetDeviceBandwidth(); + } + logprintf(4, "Stats: File Copy: %.2fM at %.2fMB/s\n", + file_data, + file_bandwidth); +} + +void Sat::CheckStats() { + float check_data = 0.; + float check_bandwidth = 0.; + WorkerMap::const_iterator check_it = workers_map_.find( + static_cast(kCheckType)); + sat_assert(check_it != workers_map_.end()); + for (WorkerVector::const_iterator it = check_it->second->begin(); + it != check_it->second->end(); ++it) { + check_data += (*it)->GetMemoryCopiedData(); + check_bandwidth += (*it)->GetMemoryBandwidth(); + } + logprintf(4, "Stats: Data Check: %.2fM at %.2fMB/s\n", + check_data, + check_bandwidth); +} + +void Sat::NetStats() { + float net_data = 0.; + float net_bandwidth = 0.; + WorkerMap::const_iterator netio_it = workers_map_.find( + static_cast(kNetIOType)); + WorkerMap::const_iterator netslave_it = workers_map_.find( + static_cast(kNetSlaveType)); + sat_assert(netio_it != workers_map_.end()); + sat_assert(netslave_it != workers_map_.end()); + for (WorkerVector::const_iterator it = netio_it->second->begin(); + it != netio_it->second->end(); ++it) { + net_data += (*it)->GetDeviceCopiedData(); + net_bandwidth += (*it)->GetDeviceBandwidth(); + } + for (WorkerVector::const_iterator it = netslave_it->second->begin(); + it != netslave_it->second->end(); ++it) { + net_data += (*it)->GetDeviceCopiedData(); + net_bandwidth += (*it)->GetDeviceBandwidth(); + } + logprintf(4, "Stats: Net Copy: %.2fM at %.2fMB/s\n", + net_data, + net_bandwidth); +} + +void Sat::InvertStats() { + float invert_data = 0.; + float invert_bandwidth = 0.; + WorkerMap::const_iterator invert_it = workers_map_.find( + static_cast(kInvertType)); + sat_assert(invert_it != workers_map_.end()); + for (WorkerVector::const_iterator it = invert_it->second->begin(); + it != invert_it->second->end(); ++it) { + invert_data += (*it)->GetMemoryCopiedData(); + invert_bandwidth += (*it)->GetMemoryBandwidth(); + } + logprintf(4, "Stats: Invert Data: %.2fM at %.2fMB/s\n", + invert_data, + invert_bandwidth); +} + +void Sat::DiskStats() { + float disk_data = 0.; + float disk_bandwidth = 0.; + WorkerMap::const_iterator disk_it = workers_map_.find( + static_cast(kDiskType)); + WorkerMap::const_iterator random_it = workers_map_.find( + static_cast(kRandomDiskType)); + sat_assert(disk_it != workers_map_.end()); + sat_assert(random_it != workers_map_.end()); + for (WorkerVector::const_iterator it = disk_it->second->begin(); + it != disk_it->second->end(); ++it) { + disk_data += (*it)->GetDeviceCopiedData(); + disk_bandwidth += (*it)->GetDeviceBandwidth(); + } + for (WorkerVector::const_iterator it = random_it->second->begin(); + it != random_it->second->end(); ++it) { + disk_data += (*it)->GetDeviceCopiedData(); + disk_bandwidth += (*it)->GetDeviceBandwidth(); + } + + logprintf(4, "Stats: Disk: %.2fM at %.2fMB/s\n", + disk_data, + disk_bandwidth); +} + +// Process worker thread data for bandwidth information, and error results. +// You can add more methods here just subclassing SAT. +void Sat::RunAnalysis() { + AnalysisAllStats(); + MemoryStats(); + FileStats(); + NetStats(); + CheckStats(); + InvertStats(); + DiskStats(); +} + +// Get total error count, summing across all threads.. +int64 Sat::GetTotalErrorCount() { + int64 errors = 0; + + AcquireWorkerLock(); + for (WorkerMap::const_iterator map_it = workers_map_.begin(); + map_it != workers_map_.end(); ++map_it) { + for (WorkerVector::const_iterator it = map_it->second->begin(); + it != map_it->second->end(); ++it) { + errors += (*it)->GetErrorCount(); + } + } + ReleaseWorkerLock(); + return errors; +} + + +void Sat::SpawnThreads() { + logprintf(12, "Log: Initializing WorkerStatus objects\n"); + power_spike_status_.Initialize(); + continuous_status_.Initialize(); + logprintf(12, "Log: Spawning worker threads\n"); + for (WorkerMap::const_iterator map_it = workers_map_.begin(); + map_it != workers_map_.end(); ++map_it) { + for (WorkerVector::const_iterator it = map_it->second->begin(); + it != map_it->second->end(); ++it) { + logprintf(12, "Log: Spawning thread %d\n", (*it)->ThreadID()); + (*it)->SpawnThread(); + } + } +} + +// Delete used worker thread objects. +void Sat::DeleteThreads() { + logprintf(12, "Log: Deleting worker threads\n"); + for (WorkerMap::const_iterator map_it = workers_map_.begin(); + map_it != workers_map_.end(); ++map_it) { + for (WorkerVector::const_iterator it = map_it->second->begin(); + it != map_it->second->end(); ++it) { + logprintf(12, "Log: Deleting thread %d\n", (*it)->ThreadID()); + delete (*it); + } + delete map_it->second; + } + workers_map_.clear(); + logprintf(12, "Log: Destroying WorkerStatus objects\n"); + power_spike_status_.Destroy(); + continuous_status_.Destroy(); +} + +namespace { +// Calculates the next time an action in Sat::Run() should occur, based on a +// schedule derived from a start point and a regular frequency. +// +// Using frequencies instead of intervals with their accompanying drift allows +// users to better predict when the actions will occur throughout a run. +// +// Arguments: +// frequency: seconds +// start: unixtime +// now: unixtime +// +// Returns: unixtime +inline time_t NextOccurance(time_t frequency, time_t start, time_t now) { + return start + frequency + (((now - start) / frequency) * frequency); +} +} + +// Run the actual test. +bool Sat::Run() { + // Install signal handlers to gracefully exit in the middle of a run. + // + // Why go through this whole rigmarole? It's the only standards-compliant + // (C++ and POSIX) way to handle signals in a multithreaded program. + // Specifically: + // + // 1) (C++) The value of a variable not of type "volatile sig_atomic_t" is + // unspecified upon entering a signal handler and, if modified by the + // handler, is unspecified after leaving the handler. + // + // 2) (POSIX) After the value of a variable is changed in one thread, another + // thread is only guaranteed to see the new value after both threads have + // acquired or released the same mutex or rwlock, synchronized to the + // same barrier, or similar. + // + // #1 prevents the use of #2 in a signal handler, so the signal handler must + // be called in the same thread that reads the "volatile sig_atomic_t" + // variable it sets. We enforce that by blocking the signals in question in + // the worker threads, forcing them to be handled by this thread. + logprintf(12, "Log: Installing signal handlers\n"); + sigset_t new_blocked_signals; + sigemptyset(&new_blocked_signals); + sigaddset(&new_blocked_signals, SIGINT); + sigaddset(&new_blocked_signals, SIGTERM); + sigset_t prev_blocked_signals; + pthread_sigmask(SIG_BLOCK, &new_blocked_signals, &prev_blocked_signals); + sighandler_t prev_sigint_handler = signal(SIGINT, SatHandleBreak); + sighandler_t prev_sigterm_handler = signal(SIGTERM, SatHandleBreak); + + // Kick off all the worker threads. + logprintf(12, "Log: Launching worker threads\n"); + InitializeThreads(); + SpawnThreads(); + pthread_sigmask(SIG_SETMASK, &prev_blocked_signals, NULL); + + logprintf(12, "Log: Starting countdown with %d seconds\n", runtime_seconds_); + + // In seconds. + static const time_t kSleepFrequency = 5; + // All of these are in seconds. You probably want them to be >= + // kSleepFrequency and multiples of kSleepFrequency, but neither is necessary. + static const time_t kInjectionFrequency = 10; + static const time_t kPrintFrequency = 10; + + const time_t start = time(NULL); + const time_t end = start + runtime_seconds_; + time_t now = start; + time_t next_print = start + kPrintFrequency; + time_t next_pause = start + pause_delay_; + time_t next_resume = 0; + time_t next_injection; + if (crazy_error_injection_) { + next_injection = start + kInjectionFrequency; + } else { + next_injection = 0; + } + + while (now < end) { + // This is an int because it's for logprintf(). + const int seconds_remaining = end - now; + + if (user_break_) { + // Handle early exit. + logprintf(0, "Log: User exiting early (%d seconds remaining)\n", + seconds_remaining); + break; + } + + // If we have an error limit, check it here and see if we should exit. + if (max_errorcount_ != 0) { + uint64 errors = GetTotalErrorCount(); + if (errors > max_errorcount_) { + logprintf(0, "Log: Exiting early (%d seconds remaining) " + "due to excessive failures (%lld)\n", + seconds_remaining, + errors); + break; + } + } + + if (now >= next_print) { + // Print a count down message. + logprintf(5, "Log: Seconds remaining: %d\n", seconds_remaining); + next_print = NextOccurance(kPrintFrequency, start, now); + } + + if (next_injection && now >= next_injection) { + // Inject an error. + logprintf(4, "Log: Injecting error (%d seconds remaining)\n", + seconds_remaining); + struct page_entry src; + GetValid(&src); + src.pattern = patternlist_->GetPattern(0); + PutValid(&src); + next_injection = NextOccurance(kInjectionFrequency, start, now); + } + + if (next_pause && now >= next_pause) { + // Tell worker threads to pause in preparation for a power spike. + logprintf(4, "Log: Pausing worker threads in preparation for power spike " + "(%d seconds remaining)\n", seconds_remaining); + power_spike_status_.PauseWorkers(); + logprintf(12, "Log: Worker threads paused\n"); + next_pause = 0; + next_resume = now + pause_duration_; + } + + if (next_resume && now >= next_resume) { + // Tell worker threads to resume in order to cause a power spike. + logprintf(4, "Log: Resuming worker threads to cause a power spike (%d " + "seconds remaining)\n", seconds_remaining); + power_spike_status_.ResumeWorkers(); + logprintf(12, "Log: Worker threads resumed\n"); + next_pause = NextOccurance(pause_delay_, start, now); + next_resume = 0; + } + + sat_sleep(NextOccurance(kSleepFrequency, start, now) - now); + now = time(NULL); + } + + JoinThreads(); + + logprintf(0, "Stats: Found %lld hardware incidents\n", errorcount_); + + if (!monitor_mode_) + RunAnalysis(); + + DeleteThreads(); + + logprintf(12, "Log: Uninstalling signal handlers\n"); + signal(SIGINT, prev_sigint_handler); + signal(SIGTERM, prev_sigterm_handler); + + return true; +} + +// Clean up all resources. +bool Sat::Cleanup() { + g_sat = NULL; + Logger::GlobalLogger()->StopThread(); + Logger::GlobalLogger()->SetStdoutOnly(); + if (logfile_) { + close(logfile_); + logfile_ = 0; + } + if (patternlist_) { + patternlist_->Destroy(); + delete patternlist_; + patternlist_ = 0; + } + if (os_) { + os_->FreeTestMem(); + delete os_; + os_ = 0; + } + if (empty_) { + delete empty_; + empty_ = 0; + } + if (valid_) { + delete valid_; + valid_ = 0; + } + if (finelock_q_) { + delete finelock_q_; + finelock_q_ = 0; + } + if (page_bitmap_) { + delete[] page_bitmap_; + } + + for (int i = 0; i < blocktables_.size(); i++) { + delete blocktables_[i]; + } + + if (cc_cacheline_data_) { + // The num integer arrays for all the cacheline structures are + // allocated as a single chunk. The pointers in the cacheline struct + // are populated accordingly. Hence calling free on the first + // cacheline's num's address is going to free the entire array. + // TODO(aganti): Refactor this to have a class for the cacheline + // structure (currently defined in worker.h) and clean this up + // in the destructor of that class. + if (cc_cacheline_data_[0].num) { + free(cc_cacheline_data_[0].num); + } + free(cc_cacheline_data_); + } + + sat_assert(0 == pthread_mutex_destroy(&worker_lock_)); + + return true; +} + + +// Pretty print really obvious results. +bool Sat::PrintResults() { + bool result = true; + + logprintf(4, "\n"); + if (statuscount_) { + logprintf(4, "Status: FAIL - test encountered procedural errors\n"); + result = false; + } else if (errorcount_) { + logprintf(4, "Status: FAIL - test discovered HW problems\n"); + result = false; + } else { + logprintf(4, "Status: PASS - please verify no corrected errors\n"); + } + logprintf(4, "\n"); + + return result; +} + +// Helper functions. +void Sat::AcquireWorkerLock() { + sat_assert(0 == pthread_mutex_lock(&worker_lock_)); +} +void Sat::ReleaseWorkerLock() { + sat_assert(0 == pthread_mutex_unlock(&worker_lock_)); +} + +void logprintf(int priority, const char *format, ...) { + va_list args; + va_start(args, format); + Logger::GlobalLogger()->VLogF(priority, format, args); + va_end(args); +} diff --git a/src/sat.h b/src/sat.h new file mode 100644 index 0000000..b1ad085 --- /dev/null +++ b/src/sat.h @@ -0,0 +1,309 @@ +// Copyright 2006 Google Inc. All Rights Reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// sat.h : sat stress test object interface and data structures + +#ifndef STRESSAPPTEST_SAT_H_ +#define STRESSAPPTEST_SAT_H_ + +#include + +#include +#include +#include + +// This file must work with autoconf on its public version, +// so these includes are correct. +#include "finelock_queue.h" +#include "queue.h" +#include "sattypes.h" +#include "worker.h" +#include "os.h" + +// SAT stress test class. +class Sat { + public: + // Enum for page queue implementation switch. + enum PageQueueType { SAT_ONELOCK, SAT_FINELOCK }; + + Sat(); + virtual ~Sat(); + + // Read configuration from arguments. Called first. + bool ParseArgs(int argc, char **argv); + virtual bool CheckGoogleSpecificArgs(int argc, char **argv, int *i); + // Initialize data structures, subclasses, and resources, + // based on command line args. + // Called after ParseArgs(). + bool Initialize(); + + // Execute the test. Initialize() and ParseArgs() must be called first. + // This must be called from a single-threaded program. + bool Run(); + + // Pretty print result summary. + // Called after Run(). + // Return value is success or failure of the SAT run, *not* of this function! + bool PrintResults(); + + // Pretty print version info. + bool PrintVersion(); + + // Pretty print help. + virtual void PrintHelp(); + + // Clean up allocations and resources. + // Called last. + bool Cleanup(); + + // Abort Run(). Only for use by Run()-installed signal handlers. + void Break() { user_break_ = true; } + + // Fetch and return empty and full pages into the empty and full pools. + bool GetValid(struct page_entry *pe); + bool PutValid(struct page_entry *pe); + bool GetEmpty(struct page_entry *pe); + bool PutEmpty(struct page_entry *pe); + + bool GetValid(struct page_entry *pe, int32 tag); + bool GetEmpty(struct page_entry *pe, int32 tag); + + // Accessor functions. + int verbosity() const { return verbosity_; } + int logfile() const { return logfile_; } + int page_length() const { return page_length_; } + int disk_pages() const { return disk_pages_; } + int strict() const { return strict_; } + int tag_mode() const { return tag_mode_; } + int status() const { return statuscount_; } + void bad_status() { statuscount_++; } + int errors() const { return errorcount_; } + int warm() const { return warm_; } + bool stop_on_error() const { return stop_on_error_; } + int32 region_mask() const { return region_mask_; } + // Semi-accessor to find the "nth" region to avoid replicated bit searching.. + int32 region_find(int32 num) const { + for (int i = 0; i < 32; i++) { + if ((1 << i) & region_mask_) { + if (num == 0) + return i; + num--; + } + } + return 0; + } + + // Causes false errors for unittesting. + // Setting to "true" causes errors to be injected. + void set_error_injection(bool errors) { error_injection_ = errors; } + bool error_injection() const { return error_injection_; } + + protected: + // Opens log file for writing. Returns 0 on failure. + bool InitializeLogfile(); + // Checks for supported environment. Returns 0 on failure. + bool CheckEnvironment(); + // Allocates size_ bytes of test memory. + bool AllocateMemory(); + // Initializes datapattern reference structures. + bool InitializePatterns(); + // Initializes test memory with datapatterns. + bool InitializePages(); + + // Start up worker threads. + virtual void InitializeThreads(); + // Spawn worker threads. + void SpawnThreads(); + // Reap worker threads. + void JoinThreads(); + // Run bandwidth and error analysis. + virtual void RunAnalysis(); + // Delete worker threads. + void DeleteThreads(); + + // Return the number of cpus in the system. + int CpuCount(); + + // Collect error counts from threads. + int64 GetTotalErrorCount(); + + // Command line arguments. + string cmdline_; + + // Memory and test configuration. + int runtime_seconds_; // Seconds to run. + int page_length_; // Length of each memory block. + int64 pages_; // Number of memory blocks. + int64 size_; // Size of memory tested, in bytes. + int64 size_mb_; // Size of memory tested, in MB. + int64 freepages_; // How many invalid pages we need. + int disk_pages_; // Number of pages per temp file. + uint64 paddr_base_; // Physical address base. + + // Control flags. + volatile sig_atomic_t user_break_; // User has signalled early exit. Used as + // a boolean. + int verbosity_; // How much to print. + int strict_; // Check results per transaction. + int warm_; // FPU warms CPU while coying. + int address_mode_; // 32 or 64 bit binary. + bool stop_on_error_; // Exit immendiately on any error. + bool findfiles_; // Autodetect tempfile locations. + + bool error_injection_; // Simulate errors, for unittests. + bool crazy_error_injection_; // Simulate lots of errors. + int64 max_errorcount_; // Number of errors before forced exit. + int run_on_anything_; // Ignore unknown machine ereor. + int use_logfile_; // Log to a file. + char logfilename_[255]; // Name of file to log to. + int logfile_; // File handle to log to. + + // Disk thread options. + int read_block_size_; // Size of block to read from disk. + int write_block_size_; // Size of block to write to disk. + int64 segment_size_; // Size of segment to split disk into. + int cache_size_; // Size of disk cache. + int blocks_per_segment_; // Number of blocks to test per segment. + int read_threshold_; // Maximum time (in us) a read should take + // before warning of a slow read. + int write_threshold_; // Maximum time (in us) a write should + // take before warning of a slow write. + int non_destructive_; // Whether to use non-destructive mode for + // the disk test. + + // Generic Options. + int monitor_mode_; // Switch for monitor-only mode SAT. + // This switch trumps most of the other + // argument, as SAT will only run error + // polling threads. + int tag_mode_; // Do tagging of memory and strict + // checking for misplaced cachelines. + + bool do_page_map_; // Should we print a list of used pages? + unsigned char *page_bitmap_; // Store bitmap of physical pages seen. + uint64 page_bitmap_size_; // Length of physical memory represented. + + // Cpu Cache Coherency Options. + bool cc_test_; // Flag to decide whether to start the + // cache coherency threads. + int cc_cacheline_count_; // Number of cache line size structures. + int cc_inc_count_; // Number of times to increment the shared + // cache lines structure members. + + // Thread control. + int file_threads_; // Threads of file IO. + int net_threads_; // Threads of network IO. + int listen_threads_; // Threads for network IO to connect. + int memory_threads_; // Threads of memcpy. + int invert_threads_; // Threads of invert. + int fill_threads_; // Threads of memset. + int check_threads_; // Threads of strcmp. + int cpu_stress_threads_; // Threads of CPU stress workload. + int disk_threads_; // Threads of disk test. + int random_threads_; // Number of random disk threads. + int total_threads_; // Total threads used. + bool error_poll_; // Poll for system errors. + + // Resources. + cc_cacheline_data *cc_cacheline_data_; // The cache line sized datastructure + // used by the ccache threads + // (in worker.h). + vector filename_; // Filenames for file IO. + vector ipaddrs_; // Addresses for network IO. + vector diskfilename_; // Filename for disk IO device. + // Block table for IO device. + vector blocktables_; + + int32 region_mask_; // Bitmask of available NUMA regions. + int32 region_count_; // Count of available NUMA regions. + int32 region_[32]; // Pagecount per region. + int region_mode_; // What to do with NUMA hints? + static const int kLocalNuma = 1; // Target local memory. + static const int kRemoteNuma = 2; // Target remote memory. + + // Results. + int64 errorcount_; // Total hardware incidents seen. + int statuscount_; // Total test errors seen. + + // Thread type constants and types + enum ThreadType { + kMemoryType = 0, + kFileIOType = 1, + kNetIOType = 2, + kNetSlaveType = 3, + kCheckType = 4, + kInvertType = 5, + kDiskType = 6, + kRandomDiskType = 7, + kCPUType = 8, + kErrorType = 9, + kCCType = 10 + }; + + // Helper functions. + virtual void AcquireWorkerLock(); + virtual void ReleaseWorkerLock(); + pthread_mutex_t worker_lock_; // Lock access to the worker thread structure. + typedef vector WorkerVector; + typedef map WorkerMap; + // Contains all worker threads. + WorkerMap workers_map_; + // Delay between power spikes. + time_t pause_delay_; + // The duration of each pause (for power spikes). + time_t pause_duration_; + // For the workers we pause and resume to create power spikes. + WorkerStatus power_spike_status_; + // For the workers we never pause. + WorkerStatus continuous_status_; + + class OsLayer *os_; // Os abstraction: put hacks here. + class PatternList *patternlist_; // Access to global data patterns. + + // RunAnalysis methods + void AnalysisAllStats(); // Summary of all runs. + void MemoryStats(); + void FileStats(); + void NetStats(); + void CheckStats(); + void InvertStats(); + void DiskStats(); + + void QueueStats(); + + // Physical page use reporting. + void AddrMapInit(); + void AddrMapUpdate(struct page_entry *pe); + void AddrMapPrint(); + + // additional memory data from google-specific tests. + virtual void GoogleMemoryStats(float *memcopy_data, + float *memcopy_bandwidth); + + virtual void GoogleOsOptions(std::map *options); + + // Page queues, only one of (valid_+empty_) or (finelock_q_) will be used + // at a time. A commandline switch controls which queue implementation will + // be used. + class PageEntryQueue *valid_; // Page queue structure, valid pages. + class PageEntryQueue *empty_; // Page queue structure, free pages. + class FineLockPEQueue *finelock_q_; // Page queue with fine-grain locks + Sat::PageQueueType pe_q_implementation_; // Queue implementation switch + + DISALLOW_COPY_AND_ASSIGN(Sat); +}; + +Sat *SatFactory(); + +#endif // STRESSAPPTEST_SAT_H_ diff --git a/src/sat_factory.cc b/src/sat_factory.cc new file mode 100644 index 0000000..5cf3e4c --- /dev/null +++ b/src/sat_factory.cc @@ -0,0 +1,21 @@ +// Copyright 2008 Google Inc. All Rights Reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// sat_factory.h : factory for SAT + +#include "sat.h" // NOLINT + +Sat *SatFactory() { + return new Sat(); +} diff --git a/src/sattypes.h b/src/sattypes.h new file mode 100644 index 0000000..2a58862 --- /dev/null +++ b/src/sattypes.h @@ -0,0 +1,156 @@ +// Copyright 2006 Google Inc. All Rights Reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef STRESSAPPTEST_SATTYPES_H_ +#define STRESSAPPTEST_SATTYPES_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H // Built using autoconf +#include "stressapptest_config.h" +using namespace std; +using namespace __gnu_cxx; + +typedef signed long long int64; +typedef signed int int32; +typedef signed short int int16; +typedef signed char int8; + +typedef unsigned long long uint64; +typedef unsigned int uint32; +typedef unsigned short uint16; +typedef unsigned char uint8; + +#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ + TypeName(const TypeName&); \ + void operator=(const TypeName&) + +inline const char* Timestamp() { + return STRESSAPPTEST_TIMESTAMP; +} + +inline const char* BuildChangelist() { + return "open source release"; +} + +#else + #include "googlesattypes.h" +#endif +// Workaround to allow 32/64 bit conversion +// without running into strict aliasing problems. +union datacast_t { + uint64 l64; + struct { + uint32 l; + uint32 h; + } l32; +}; + + +// File sync'd print to console and log +void logprintf(int priority, const char *format, ...); + +// We print to stderr ourselves first in case we're in such a bad state that the +// logger can't work. +#define sat_assert(x) \ +{\ + if (!(x)) {\ + fprintf(stderr, "Assertion failed at %s:%d\n", __FILE__, __LINE__);\ + logprintf(0, "Assertion failed at %s:%d\n", __FILE__, __LINE__);\ + exit(1);\ + }\ +} + +#if !defined(CPU_SETSIZE) + // Define type and macros for cpu mask operations + // Note: this code is hacked together to deal with difference + // function signatures across versions of glibc, ie those that take + // cpu_set_t versus those that take unsigned long. -johnhuang + typedef unsigned long cpu_set_t; + #define CPU_SETSIZE 32 + #define CPU_ISSET(index, cpu_set_ptr) (*(cpu_set_ptr) & 1 << (index)) + #define CPU_SET(index, cpu_set_ptr) (*(cpu_set_ptr) |= 1 << (index)) + #define CPU_ZERO(cpu_set_ptr) (*(cpu_set_ptr) = 0) + #define CPU_CLR(index, cpu_set_ptr) (*(cpu_set_ptr) &= ~(1 << (index))) +#endif + +// Make using CPUSET non-super-painful. +static inline uint32 cpuset_to_uint32(cpu_set_t *cpuset) { + uint32 value = 0; + for (int index = 0; index < CPU_SETSIZE; index++) { + if (CPU_ISSET(index, cpuset)) { + if (index < 32) { + value |= 1 << index; + } else { + logprintf(0, "Process Error: Cpu index (%d) higher than 32\n", index); + sat_assert(0); + } + } + } + return value; +} + +static inline void cpuset_from_uint32(uint32 mask, cpu_set_t *cpuset) { + CPU_ZERO(cpuset); + for (int index = 0; index < 32; index++) { + if (mask & (1 << index)) + CPU_SET(index, cpuset); + } +} + +static const int32 kUSleepOneSecond = 1000000; + +// This is guaranteed not to use signals. +inline bool sat_usleep(int32 microseconds) { + timespec req; + req.tv_sec = microseconds / 1000000; + // Convert microseconds argument to nano seconds. + req.tv_nsec = (microseconds % 1000000) * 1000; + return nanosleep(&req, NULL) == 0; +} + +// This is guaranteed not to use signals. +inline bool sat_sleep(time_t seconds) { + timespec req; + req.tv_sec = seconds; + req.tv_nsec = 0; + return nanosleep(&req, NULL) == 0; +} + +// Get an error code description for use in error messages. +// +// Args: +// error_num: an errno error code +inline string ErrorString(int error_num) { + char buf[256]; + return string(strerror_r(error_num, buf, sizeof buf)); +} + +// Define handy constants here +static const int kTicksPerSec = 100; +static const int kMegabyte = (1024LL*1024LL); +static const int kSatDiskPageMax = 32; +static const int kSatDiskPage = 8; +static const int kSatPageSize = (1024LL*1024LL); +static const int kCacheLineSize = 64; +static const uint16_t kNetworkPort = 19996; + +#endif // STRESSAPPTEST_SATTYPES_H_ diff --git a/src/stressapptest_config.h.in b/src/stressapptest_config.h.in new file mode 100644 index 0000000..efb8b2c --- /dev/null +++ b/src/stressapptest_config.h.in @@ -0,0 +1,188 @@ +/* src/stressapptest_config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if the `closedir' function returns void instead of `int'. */ +#undef CLOSEDIR_VOID + +/* Define to 1 if you have the header file. */ +#undef HAVE_ARPA_INET_H + +/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you + don't. */ +#undef HAVE_DECL_STRERROR_R + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_DIRENT_H + +/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ +#undef HAVE_DOPRNT + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the `gettimeofday' function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MALLOC_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `memset' function. */ +#undef HAVE_MEMSET + +/* Define to 1 if you have the header file, and it defines `DIR'. */ +#undef HAVE_NDIR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETDB_H + +/* Define to 1 if you have the `select' function. */ +#undef HAVE_SELECT + +/* Define to 1 if you have the `socket' function. */ +#undef HAVE_SOCKET + +/* Define to 1 if stdbool.h conforms to C99. */ +#undef HAVE_STDBOOL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strerror_r' function. */ +#undef HAVE_STRERROR_R + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strtol' function. */ +#undef HAVE_STRTOL + +/* Define to 1 if you have the `strtoull' function. */ +#undef HAVE_STRTOULL + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_SYS_DIR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_IOCTL_H + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_SYS_NDIR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `vprintf' function. */ +#undef HAVE_VPRINTF + +/* Define to 1 if the system has the type `_Bool'. */ +#undef HAVE__BOOL + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define as the return type of signal handlers (`int' or `void'). */ +#undef RETSIGTYPE + +/* Define to the type of arg 1 for `select'. */ +#undef SELECT_TYPE_ARG1 + +/* Define to the type of args 2, 3 and 4 for `select'. */ +#undef SELECT_TYPE_ARG234 + +/* Define to the type of arg 5 for `select'. */ +#undef SELECT_TYPE_ARG5 + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if strerror_r returns char *. */ +#undef STRERROR_R_CHAR_P + +/* Defined if the target CPU is i686 */ +#undef STRESSAPPTEST_CPU_I686 + +/* Defined if the target CPU is PowerPC */ +#undef STRESSAPPTEST_CPU_PPC + +/* Defined if the target CPU is x86_64 */ +#undef STRESSAPPTEST_CPU_X86_64 + +/* Timestamp when ./configure was executed */ +#undef STRESSAPPTEST_TIMESTAMP + +/* Define to 1 if you can safely include both and . */ +#undef TIME_WITH_SYS_TIME + +/* Version number of package */ +#undef VERSION + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to `int' if does not define. */ +#undef pid_t + +/* Define to equivalent of C99 restrict keyword, or to nothing if this is not + supported. Do not define if restrict is supported directly. */ +#undef restrict + +/* Define to `int' if does not define. */ +#undef ssize_t + +/* Define to the type of an unsigned integer type of width exactly 16 bits if + such a type exists and the standard includes do not define it. */ +#undef uint16_t + +/* Define to empty if the keyword `volatile' does not work. Warning: valid + code using `volatile' can become incorrect without. Disable with care. */ +#undef volatile diff --git a/src/worker.cc b/src/worker.cc new file mode 100644 index 0000000..6a00db2 --- /dev/null +++ b/src/worker.cc @@ -0,0 +1,3258 @@ +// Copyright 2006 Google Inc. All Rights Reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// worker.cc : individual tasks that can be run in combination to +// stress the system + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +// These are necessary, but on by default +// #define __USE_GNU +// #define __USE_LARGEFILE64 +#include +#include +#include +#include +#include // for gettid +// For size of block device +#include +#include +// For asynchronous I/O +#include + +#include + +#include +#include + +// This file must work with autoconf on its public version, +// so these includes are correct. +#include "error_diag.h" // NOLINT +#include "os.h" // NOLINT +#include "pattern.h" // NOLINT +#include "queue.h" // NOLINT +#include "sat.h" // NOLINT +#include "sattypes.h" // NOLINT +#include "worker.h" // NOLINT + +// Syscalls +// Why ubuntu, do you hate gettid so bad? +#if !defined(__NR_gettid) +# define __NR_gettid 224 +#endif + +#define gettid() syscall(__NR_gettid) +#if !defined(CPU_SETSIZE) +_syscall3(int, sched_getaffinity, pid_t, pid, + unsigned int, len, cpu_set_t*, mask) +_syscall3(int, sched_setaffinity, pid_t, pid, + unsigned int, len, cpu_set_t*, mask) +#endif + +// Linux aio syscalls. +#if !defined(__NR_io_setup) +#define __NR_io_setup 206 +#define __NR_io_destroy 207 +#define __NR_io_getevents 208 +#define __NR_io_submit 209 +#define __NR_io_cancel 210 +#endif + +#define io_setup(nr_events, ctxp) \ + syscall(__NR_io_setup, (nr_events), (ctxp)) +#define io_submit(ctx_id, nr, iocbpp) \ + syscall(__NR_io_submit, (ctx_id), (nr), (iocbpp)) +#define io_getevents(ctx_id, io_getevents, nr, events, timeout) \ + syscall(__NR_io_getevents, (ctx_id), (io_getevents), (nr), (events), \ + (timeout)) +#define io_cancel(ctx_id, iocb, result) \ + syscall(__NR_io_cancel, (ctx_id), (iocb), (result)) +#define io_destroy(ctx) \ + syscall(__NR_io_destroy, (ctx)) + +namespace { + // Get HW core ID from cpuid instruction. + inline int apicid(void) { + int cpu; +#ifdef STRESSAPPTEST_CPU_PPC + cpu = 0; +#else + __asm __volatile("cpuid" : "=b" (cpu) : "a" (1) : "cx", "dx"); +#endif + return (cpu >> 24); + } + + // Work around the sad fact that there are two (gnu, xsi) incompatible + // versions of strerror_r floating around google. Awesome. + bool sat_strerror(int err, char *buf, int len) { + buf[0] = 0; + char *errmsg = reinterpret_cast(strerror_r(err, buf, len)); + int retval = reinterpret_cast(errmsg); + if (retval == 0) + return true; + if (retval == -1) + return false; + if (errmsg != buf) { + strncpy(buf, errmsg, len); + buf[len - 1] = 0; + } + return true; + } + + + inline uint64 addr_to_tag(void *address) { + return reinterpret_cast(address); + } +} + +#if !defined(O_DIRECT) +// Sometimes this isn't available. +// Disregard if it's not defined. + #define O_DIRECT 0 +#endif + +// A struct to hold captured errors, for later reporting. +struct ErrorRecord { + uint64 actual; // This is the actual value read. + uint64 reread; // This is the actual value, reread. + uint64 expected; // This is what it should have been. + uint64 *vaddr; // This is where it was (or wasn't). + char *vbyteaddr; // This is byte specific where the data was (or wasn't). + uint64 paddr; // This is the bus address, if available. + uint64 *tagvaddr; // This holds the tag value if this data was tagged. + uint64 tagpaddr; // This holds the physical address corresponding to the tag. +}; + +// This is a helper function to create new threads with pthreads. +static void *ThreadSpawnerGeneric(void *ptr) { + WorkerThread *worker = static_cast(ptr); + worker->StartRoutine(); + return NULL; +} + + +void WorkerStatus::Initialize() { + sat_assert(0 == pthread_mutex_init(&num_workers_mutex_, NULL)); + sat_assert(0 == pthread_rwlock_init(&status_rwlock_, NULL)); + sat_assert(0 == pthread_barrier_init(&pause_barrier_, NULL, + num_workers_ + 1)); +} + +void WorkerStatus::Destroy() { + sat_assert(0 == pthread_mutex_destroy(&num_workers_mutex_)); + sat_assert(0 == pthread_rwlock_destroy(&status_rwlock_)); + sat_assert(0 == pthread_barrier_destroy(&pause_barrier_)); +} + +void WorkerStatus::PauseWorkers() { + if (SetStatus(PAUSE) != PAUSE) + WaitOnPauseBarrier(); +} + +void WorkerStatus::ResumeWorkers() { + if (SetStatus(RUN) == PAUSE) + WaitOnPauseBarrier(); +} + +void WorkerStatus::StopWorkers() { + if (SetStatus(STOP) == PAUSE) + WaitOnPauseBarrier(); +} + +bool WorkerStatus::ContinueRunning() { + // This loop is an optimization. We use it to immediately re-check the status + // after resuming from a pause, instead of returning and waiting for the next + // call to this function. + for (;;) { + switch (GetStatus()) { + case RUN: + return true; + case PAUSE: + // Wait for the other workers to call this function so that + // PauseWorkers() can return. + WaitOnPauseBarrier(); + // Wait for ResumeWorkers() to be called. + WaitOnPauseBarrier(); + break; + case STOP: + return false; + } + } +} + +bool WorkerStatus::ContinueRunningNoPause() { + return (GetStatus() != STOP); +} + +void WorkerStatus::RemoveSelf() { + // Acquire a read lock on status_rwlock_ while (status_ != PAUSE). + for (;;) { + AcquireStatusReadLock(); + if (status_ != PAUSE) + break; + // We need to obey PauseWorkers() just like ContinueRunning() would, so that + // the other threads won't wait on pause_barrier_ forever. + ReleaseStatusLock(); + // Wait for the other workers to call this function so that PauseWorkers() + // can return. + WaitOnPauseBarrier(); + // Wait for ResumeWorkers() to be called. + WaitOnPauseBarrier(); + } + + // This lock would be unnecessary if we held a write lock instead of a read + // lock on status_rwlock_, but that would also force all threads calling + // ContinueRunning() to wait on this one. Using a separate lock avoids that. + AcquireNumWorkersLock(); + // Decrement num_workers_ and reinitialize pause_barrier_, which we know isn't + // in use because (status != PAUSE). + sat_assert(0 == pthread_barrier_destroy(&pause_barrier_)); + sat_assert(0 == pthread_barrier_init(&pause_barrier_, NULL, num_workers_)); + --num_workers_; + ReleaseNumWorkersLock(); + + // Release status_rwlock_. + ReleaseStatusLock(); +} + + +// Parent thread class. +WorkerThread::WorkerThread() { + status_ = 0; + pages_copied_ = 0; + errorcount_ = 0; + runduration_usec_ = 0; + priority_ = Normal; + worker_status_ = NULL; + thread_spawner_ = &ThreadSpawnerGeneric; + tag_mode_ = false; +} + +WorkerThread::~WorkerThread() {} + +// Constructors. Just init some default values. +FillThread::FillThread() { + num_pages_to_fill_ = 0; +} + +// Initialize file name to empty. +FileThread::FileThread() { + filename_ = ""; + devicename_ = ""; + pass_ = 0; + page_io_ = true; + crc_page_ = -1; +} + +// If file thread used bounce buffer in memory, account for the extra +// copy for memory bandwidth calculation. +float FileThread::GetMemoryCopiedData() { + if (!os_->normal_mem()) + return GetCopiedData(); + else + return 0; +} + +// Initialize target hostname to be invalid. +NetworkThread::NetworkThread() { + snprintf(ipaddr_, sizeof(ipaddr_), "Unknown"); + sock_ = 0; +} + +// Initialize? +NetworkSlaveThread::NetworkSlaveThread() { +} + +// Initialize? +NetworkListenThread::NetworkListenThread() { +} + +// Init member variables. +void WorkerThread::InitThread(int thread_num_init, + class Sat *sat_init, + class OsLayer *os_init, + class PatternList *patternlist_init, + WorkerStatus *worker_status) { + sat_assert(worker_status); + worker_status->AddWorkers(1); + + thread_num_ = thread_num_init; + sat_ = sat_init; + os_ = os_init; + patternlist_ = patternlist_init; + worker_status_ = worker_status; + + cpu_mask_ = AvailableCpus(); + tag_ = 0xffffffff; + + tag_mode_ = sat_->tag_mode(); +} + + +// Use pthreads to prioritize a system thread. +bool WorkerThread::InitPriority() { + // This doesn't affect performance that much, and may not be too safe. + + bool ret = BindToCpus(cpu_mask_); + if (!ret) + logprintf(11, "Log: Bind to %x failed.\n", cpu_mask_); + + logprintf(11, "Log: Thread %d running on apic ID %d mask %x (%x).\n", + thread_num_, apicid(), CurrentCpus(), cpu_mask_); +#if 0 + if (priority_ == High) { + sched_param param; + param.sched_priority = 1; + // Set the priority; others are unchanged. + logprintf(0, "Log: Changing priority to SCHED_FIFO %d\n", + param.sched_priority); + if (sched_setscheduler(0, SCHED_FIFO, ¶m)) { + char buf[256]; + sat_strerror(errno, buf, sizeof(buf)); + logprintf(0, "Process Error: sched_setscheduler " + "failed - error %d %s\n", + errno, buf); + } + } +#endif + return true; +} + +// Use pthreads to create a system thread. +int WorkerThread::SpawnThread() { + // Create the new thread. + int result = pthread_create(&thread_, NULL, thread_spawner_, this); + if (result) { + char buf[256]; + sat_strerror(result, buf, sizeof(buf)); + logprintf(0, "Process Error: pthread_create " + "failed - error %d %s\n", result, + buf); + status_ += 1; + return false; + } + + // 0 is pthreads success. + return true; +} + +// Kill the worker thread with SIGINT. +int WorkerThread::KillThread() { + pthread_kill(thread_, SIGINT); + return 0; +} + +// Block until thread has exited. +int WorkerThread::JoinThread() { + int result = pthread_join(thread_, NULL); + + if (result) { + logprintf(0, "Process Error: pthread_join failed - error %d\n", result); + status_ = 0; + } + + // 0 is pthreads success. + return (!result); +} + + +void WorkerThread::StartRoutine() { + InitPriority(); + StartThreadTimer(); + Work(); + StopThreadTimer(); + worker_status_->RemoveSelf(); +} + + +// Thread work loop. Execute until marked finished. +int WorkerThread::Work() { + do { + logprintf(9, "Log: ...\n"); + // Sleep for 1 second. + sat_sleep(1); + } while (IsReadyToRun()); + + return 0; +} + + +// Returns CPU mask of CPUs available to this process, +// Conceptually, each bit represents a logical CPU, ie: +// mask = 3 (11b): cpu0, 1 +// mask = 13 (1101b): cpu0, 2, 3 +uint32 WorkerThread::AvailableCpus() { + cpu_set_t curr_cpus; + CPU_ZERO(&curr_cpus); + sched_getaffinity(getppid(), sizeof(curr_cpus), &curr_cpus); + return cpuset_to_uint32(&curr_cpus); +} + + +// Returns CPU mask of CPUs this thread is bound to, +// Conceptually, each bit represents a logical CPU, ie: +// mask = 3 (11b): cpu0, 1 +// mask = 13 (1101b): cpu0, 2, 3 +uint32 WorkerThread::CurrentCpus() { + cpu_set_t curr_cpus; + CPU_ZERO(&curr_cpus); + sched_getaffinity(0, sizeof(curr_cpus), &curr_cpus); + return cpuset_to_uint32(&curr_cpus); +} + + +// Bind worker thread to specified CPU(s) +// Args: +// thread_mask: cpu_set_t representing CPUs, ie +// mask = 1 (01b): cpu0 +// mask = 3 (11b): cpu0, 1 +// mask = 13 (1101b): cpu0, 2, 3 +// +// Returns true on success, false otherwise. +bool WorkerThread::BindToCpus(uint32 thread_mask) { + uint32 process_mask = AvailableCpus(); + if (thread_mask == process_mask) + return true; + + logprintf(11, "Log: available CPU mask - %x\n", process_mask); + if ((thread_mask | process_mask) != process_mask) { + // Invalid cpu_mask, ie cpu not allocated to this process or doesn't exist. + logprintf(0, "Log: requested CPUs %x not a subset of available %x\n", + thread_mask, process_mask); + return false; + } + cpu_set_t cpuset; + cpuset_from_uint32(thread_mask, &cpuset); + return (sched_setaffinity(gettid(), sizeof(cpuset), &cpuset) == 0); +} + + +// A worker thread can yield itself to give up CPU until it's scheduled again. +// Returns true on success, false on error. +bool WorkerThread::YieldSelf() { + return (sched_yield() == 0); +} + + +// Fill this page with its pattern. +bool WorkerThread::FillPage(struct page_entry *pe) { + // Error check arguments. + if (pe == 0) { + logprintf(0, "Process Error: Fill Page entry null\n"); + return 0; + } + + // Mask is the bitmask of indexes used by the pattern. + // It is the pattern size -1. Size is always a power of 2. + uint64 *memwords = static_cast(pe->addr); + int length = sat_->page_length(); + + if (tag_mode_) { + // Select tag or data as appropriate. + for (int i = 0; i < length / wordsize_; i++) { + datacast_t data; + + if ((i & 0x7) == 0) { + data.l64 = addr_to_tag(&memwords[i]); + } else { + data.l32.l = pe->pattern->pattern(i << 1); + data.l32.h = pe->pattern->pattern((i << 1) + 1); + } + memwords[i] = data.l64; + } + } else { + // Just fill in untagged data directly. + for (int i = 0; i < length / wordsize_; i++) { + datacast_t data; + + data.l32.l = pe->pattern->pattern(i << 1); + data.l32.h = pe->pattern->pattern((i << 1) + 1); + memwords[i] = data.l64; + } + } + + return 1; +} + + +// Tell the thread how many pages to fill. +void FillThread::SetFillPages(int64 num_pages_to_fill_init) { + num_pages_to_fill_ = num_pages_to_fill_init; +} + +// Fill this page with a random pattern. +bool FillThread::FillPageRandom(struct page_entry *pe) { + // Error check arguments. + if (pe == 0) { + logprintf(0, "Process Error: Fill Page entry null\n"); + return 0; + } + if ((patternlist_ == 0) || (patternlist_->Size() == 0)) { + logprintf(0, "Process Error: No data patterns available\n"); + return 0; + } + + // Choose a random pattern for this block. + pe->pattern = patternlist_->GetRandomPattern(); + if (pe->pattern == 0) { + logprintf(0, "Process Error: Null data pattern\n"); + return 0; + } + + // Actually fill the page. + return FillPage(pe); +} + + +// Memory fill work loop. Execute until alloted pages filled. +int FillThread::Work() { + int result = 1; + + logprintf(9, "Log: Starting fill thread %d\n", thread_num_); + + // We want to fill num_pages_to_fill pages, and + // stop when we've filled that many. + // We also want to capture early break + struct page_entry pe; + int64 loops = 0; + while (IsReadyToRun() && (loops < num_pages_to_fill_)) { + result &= sat_->GetEmpty(&pe); + if (!result) { + logprintf(0, "Process Error: fill_thread failed to pop pages, " + "bailing\n"); + break; + } + + // Fill the page with pattern + result &= FillPageRandom(&pe); + if (!result) break; + + // Put the page back on the queue. + result &= sat_->PutValid(&pe); + if (!result) { + logprintf(0, "Process Error: fill_thread failed to push pages, " + "bailing\n"); + break; + } + loops++; + } + + // Fill in thread status. + pages_copied_ = loops; + status_ = result; + logprintf(9, "Log: Completed %d: Fill thread. Status %d, %d pages filled\n", + thread_num_, status_, pages_copied_); + return 0; +} + + +// Print error information about a data miscompare. +void WorkerThread::ProcessError(struct ErrorRecord *error, + int priority, + const char *message) { + char dimm_string[256] = ""; + + int apic_id = apicid(); + uint32 cpumask = CurrentCpus(); + + // Determine if this is a write or read error. + os_->Flush(error->vaddr); + error->reread = *(error->vaddr); + + char *good = reinterpret_cast(&(error->expected)); + char *bad = reinterpret_cast(&(error->actual)); + + sat_assert(error->expected != error->actual); + unsigned int offset = 0; + for (offset = 0; offset < (sizeof(error->expected) - 1); offset++) { + if (good[offset] != bad[offset]) + break; + } + + error->vbyteaddr = reinterpret_cast(error->vaddr) + offset; + + // Find physical address if possible. + error->paddr = os_->VirtualToPhysical(error->vbyteaddr); + + // Pretty print DIMM mapping if available. + os_->FindDimm(error->paddr, dimm_string, sizeof(dimm_string)); + + // Report parseable error. + if (priority < 5) { + // Run miscompare error through diagnoser for logging and reporting. + os_->error_diagnoser_->AddMiscompareError(dimm_string, + reinterpret_cast + (error->vaddr), 1); + + logprintf(priority, + "%s: miscompare on CPU %d(%x) at %p(0x%llx:%s): " + "read:0x%016llx, reread:0x%016llx expected:0x%016llx\n", + message, + apic_id, + cpumask, + error->vaddr, + error->paddr, + dimm_string, + error->actual, + error->reread, + error->expected); + } + + + // Overwrite incorrect data with correct data to prevent + // future miscompares when this data is reused. + *(error->vaddr) = error->expected; + os_->Flush(error->vaddr); +} + + + +// Print error information about a data miscompare. +void FileThread::ProcessError(struct ErrorRecord *error, + int priority, + const char *message) { + char dimm_string[256] = ""; + + // Determine if this is a write or read error. + os_->Flush(error->vaddr); + error->reread = *(error->vaddr); + + char *good = reinterpret_cast(&(error->expected)); + char *bad = reinterpret_cast(&(error->actual)); + + sat_assert(error->expected != error->actual); + unsigned int offset = 0; + for (offset = 0; offset < (sizeof(error->expected) - 1); offset++) { + if (good[offset] != bad[offset]) + break; + } + + error->vbyteaddr = reinterpret_cast(error->vaddr) + offset; + + // Find physical address if possible. + error->paddr = os_->VirtualToPhysical(error->vbyteaddr); + + // Pretty print DIMM mapping if available. + os_->FindDimm(error->paddr, dimm_string, sizeof(dimm_string)); + + // If crc_page_ is valid, ie checking content read back from file, + // track src/dst memory addresses. Otherwise catagorize as general + // mememory miscompare for CRC checking everywhere else. + if (crc_page_ != -1) { + int miscompare_byteoffset = static_cast(error->vbyteaddr) - + static_cast(page_recs_[crc_page_].dst); + os_->error_diagnoser_->AddHDDMiscompareError(devicename_, + crc_page_, + miscompare_byteoffset, + page_recs_[crc_page_].src, + page_recs_[crc_page_].dst); + } else { + os_->error_diagnoser_->AddMiscompareError(dimm_string, + reinterpret_cast + (error->vaddr), 1); + } + + logprintf(priority, + "%s: miscompare on %s at %p(0x%llx:%s): read:0x%016llx, " + "reread:0x%016llx expected:0x%016llx\n", + message, + devicename_.c_str(), + error->vaddr, + error->paddr, + dimm_string, + error->actual, + error->reread, + error->expected); + + // Overwrite incorrect data with correct data to prevent + // future miscompares when this data is reused. + *(error->vaddr) = error->expected; + os_->Flush(error->vaddr); +} + + +// Do a word by word result check of a region. +// Print errors on mismatches. +int WorkerThread::CheckRegion(void *addr, + class Pattern *pattern, + int64 length, + int offset, + int64 pattern_offset) { + uint64 *memblock = static_cast(addr); + const int kErrorLimit = 128; + int errors = 0; + int overflowerrors = 0; // Count of overflowed errors. + bool page_error = false; + string errormessage("Hardware Error"); + struct ErrorRecord + recorded[kErrorLimit]; // Queued errors for later printing. + + // For each word in the data region. + for (int i = 0; i < length / wordsize_; i++) { + uint64 actual = memblock[i]; + uint64 expected; + + // Determine the value that should be there. + datacast_t data; + int index = 2 * i + pattern_offset; + data.l32.l = pattern->pattern(index); + data.l32.h = pattern->pattern(index + 1); + expected = data.l64; + // Check tags if necessary. + if (tag_mode_ && ((reinterpret_cast(&memblock[i]) & 0x3f) == 0)) { + expected = addr_to_tag(&memblock[i]); + } + + + // If the value is incorrect, save an error record for later printing. + if (actual != expected) { + if (errors < kErrorLimit) { + recorded[errors].actual = actual; + recorded[errors].expected = expected; + recorded[errors].vaddr = &memblock[i]; + errors++; + } else { + page_error = true; + // If we have overflowed the error queue, just print the errors now. + logprintf(10, "Log: Error record overflow, too many miscompares!\n"); + errormessage = "Page Error"; + break; + } + } + } + + // Find if this is a whole block corruption. + if (page_error && !tag_mode_) { + int patsize = patternlist_->Size(); + for (int pat = 0; pat < patsize; pat++) { + class Pattern *altpattern = patternlist_->GetPattern(pat); + const int kGood = 0; + const int kBad = 1; + const int kGoodAgain = 2; + const int kNoMatch = 3; + int state = kGood; + unsigned int badstart = 0; + unsigned int badend = 0; + + // Don't match against ourself! + if (pattern == altpattern) + continue; + + for (int i = 0; i < length / wordsize_; i++) { + uint64 actual = memblock[i]; + datacast_t expected; + datacast_t possible; + + // Determine the value that should be there. + int index = 2 * i + pattern_offset; + + expected.l32.l = pattern->pattern(index); + expected.l32.h = pattern->pattern(index + 1); + + possible.l32.l = pattern->pattern(index); + possible.l32.h = pattern->pattern(index + 1); + + if (state == kGood) { + if (actual == expected.l64) { + continue; + } else if (actual == possible.l64) { + badstart = i; + badend = i; + state = kBad; + continue; + } else { + state = kNoMatch; + break; + } + } else if (state == kBad) { + if (actual == possible.l64) { + badend = i; + continue; + } else if (actual == expected.l64) { + state = kGoodAgain; + continue; + } else { + state = kNoMatch; + break; + } + } else if (state == kGoodAgain) { + if (actual == expected.l64) { + continue; + } else { + state = kNoMatch; + break; + } + } + } + + if ((state == kGoodAgain) || (state == kBad)) { + unsigned int blockerrors = badend - badstart + 1; + errormessage = "Block Error"; + ProcessError(&recorded[0], 0, errormessage.c_str()); + logprintf(0, "Block Error: (%p) pattern %s instead of %s, " + "%d bytes from offset 0x%x to 0x%x\n", + &memblock[badstart], + altpattern->name(), pattern->name(), + blockerrors * wordsize_, + offset + badstart * wordsize_, + offset + badend * wordsize_); + errorcount_ += blockerrors; + return blockerrors; + } + } + } + + + // Process error queue after all errors have been recorded. + for (int err = 0; err < errors; err++) { + int priority = 5; + if (errorcount_ + err < 30) + priority = 0; // Bump up the priority for the first few errors. + ProcessError(&recorded[err], priority, errormessage.c_str()); + } + + if (page_error) { + // For each word in the data region. + int error_recount = 0; + for (int i = 0; i < length / wordsize_; i++) { + uint64 actual = memblock[i]; + uint64 expected; + datacast_t data; + // Determine the value that should be there. + int index = 2 * i + pattern_offset; + + data.l32.l = pattern->pattern(index); + data.l32.h = pattern->pattern(index + 1); + expected = data.l64; + + // Check tags if necessary. + if (tag_mode_ && ((reinterpret_cast(&memblock[i]) & 0x3f) == 0)) { + expected = addr_to_tag(&memblock[i]); + } + + // If the value is incorrect, save an error record for later printing. + if (actual != expected) { + if (error_recount < kErrorLimit) { + // We already reported these. + error_recount++; + } else { + // If we have overflowed the error queue, print the errors now. + struct ErrorRecord er; + er.actual = actual; + er.expected = expected; + er.vaddr = &memblock[i]; + + // Do the error printout. This will take a long time and + // likely change the machine state. + ProcessError(&er, 12, errormessage.c_str()); + overflowerrors++; + } + } + } + } + + // Keep track of observed errors. + errorcount_ += errors + overflowerrors; + return errors + overflowerrors; +} + +float WorkerThread::GetCopiedData() { + return pages_copied_ * sat_->page_length() / kMegabyte; +} + +// Calculate the CRC of a region. +// Result check if the CRC mismatches. +int WorkerThread::CrcCheckPage(struct page_entry *srcpe) { + const int blocksize = 4096; + const int blockwords = blocksize / wordsize_; + int errors = 0; + + const AdlerChecksum *expectedcrc = srcpe->pattern->crc(); + uint64 *memblock = static_cast(srcpe->addr); + int blocks = sat_->page_length() / blocksize; + for (int currentblock = 0; currentblock < blocks; currentblock++) { + uint64 *memslice = memblock + currentblock * blockwords; + + AdlerChecksum crc; + if (tag_mode_) { + AdlerAddrCrcC(memslice, blocksize, &crc, srcpe); + } else { + CalculateAdlerChecksum(memslice, blocksize, &crc); + } + + // If the CRC does not match, we'd better look closer. + if (!crc.Equals(*expectedcrc)) { + logprintf(11, "Log: CrcCheckPage Falling through to slow compare, " + "CRC mismatch %s != %s\n", + crc.ToHexString().c_str(), + expectedcrc->ToHexString().c_str()); + int errorcount = CheckRegion(memslice, + srcpe->pattern, + blocksize, + currentblock * blocksize, 0); + if (errorcount == 0) { + logprintf(0, "Log: CrcCheckPage CRC mismatch %s != %s, " + "but no miscompares found.\n", + crc.ToHexString().c_str(), + expectedcrc->ToHexString().c_str()); + } + errors += errorcount; + } + } + + // For odd length transfers, we should never hit this. + int leftovers = sat_->page_length() % blocksize; + if (leftovers) { + uint64 *memslice = memblock + blocks * blockwords; + errors += CheckRegion(memslice, + srcpe->pattern, + leftovers, + blocks * blocksize, 0); + } + return errors; +} + + +// Print error information about a data miscompare. +void WorkerThread::ProcessTagError(struct ErrorRecord *error, + int priority, + const char *message) { + char dimm_string[256] = ""; + char tag_dimm_string[256] = ""; + bool read_error = false; + + int apic_id = apicid(); + uint32 cpumask = CurrentCpus(); + + // Determine if this is a write or read error. + os_->Flush(error->vaddr); + error->reread = *(error->vaddr); + + // Distinguish read and write errors. + if (error->actual != error->reread) { + read_error = true; + } + + sat_assert(error->expected != error->actual); + + error->vbyteaddr = reinterpret_cast(error->vaddr); + + // Find physical address if possible. + error->paddr = os_->VirtualToPhysical(error->vbyteaddr); + error->tagpaddr = os_->VirtualToPhysical(error->tagvaddr); + + // Pretty print DIMM mapping if available. + os_->FindDimm(error->paddr, dimm_string, sizeof(dimm_string)); + // Pretty print DIMM mapping if available. + os_->FindDimm(error->tagpaddr, tag_dimm_string, sizeof(tag_dimm_string)); + + // Report parseable error. + if (priority < 5) { + logprintf(priority, + "%s: Tag from %p(0x%llx:%s) (%s) miscompare on CPU %d(%x) at " + "%p(0x%llx:%s): " + "read:0x%016llx, reread:0x%016llx expected:0x%016llx\n", + message, + error->tagvaddr, error->tagpaddr, + tag_dimm_string, + read_error?"read error":"write error", + apic_id, + cpumask, + error->vaddr, + error->paddr, + dimm_string, + error->actual, + error->reread, + error->expected); + } + + errorcount_ += 1; + + // Overwrite incorrect data with correct data to prevent + // future miscompares when this data is reused. + *(error->vaddr) = error->expected; + os_->Flush(error->vaddr); +} + + +// Print out and log a tag error. +bool WorkerThread::ReportTagError( + uint64 *mem64, + uint64 actual, + uint64 tag) { + struct ErrorRecord er; + er.actual = actual; + + er.expected = tag; + er.vaddr = mem64; + + // Generate vaddr from tag. + er.tagvaddr = reinterpret_cast(actual); + + ProcessTagError(&er, 0, "Hardware Error"); + return true; +} + +// C implementation of Adler memory copy, with memory tagging. +bool WorkerThread::AdlerAddrMemcpyC(uint64 *dstmem64, + uint64 *srcmem64, + unsigned int size_in_bytes, + AdlerChecksum *checksum, + struct page_entry *pe) { + // Use this data wrapper to access memory with 64bit read/write. + datacast_t data; + datacast_t dstdata; + unsigned int count = size_in_bytes / sizeof(data); + + if (count > ((1U) << 19)) { + // Size is too large, must be strictly less than 512 KB. + return false; + } + + uint64 a1 = 1; + uint64 a2 = 1; + uint64 b1 = 0; + uint64 b2 = 0; + + class Pattern *pattern = pe->pattern; + + unsigned int i = 0; + while (i < count) { + // Process 64 bits at a time. + if ((i & 0x7) == 0) { + data.l64 = srcmem64[i]; + dstdata.l64 = dstmem64[i]; + uint64 src_tag = addr_to_tag(&srcmem64[i]); + uint64 dst_tag = addr_to_tag(&dstmem64[i]); + // Detect if tags have been corrupted. + if (data.l64 != src_tag) + ReportTagError(&srcmem64[i], data.l64, src_tag); + if (dstdata.l64 != dst_tag) + ReportTagError(&dstmem64[i], dstdata.l64, dst_tag); + + data.l32.l = pattern->pattern(i << 1); + data.l32.h = pattern->pattern((i << 1) + 1); + a1 = a1 + data.l32.l; + b1 = b1 + a1; + a1 = a1 + data.l32.h; + b1 = b1 + a1; + + data.l64 = dst_tag; + dstmem64[i] = data.l64; + + } else { + data.l64 = srcmem64[i]; + a1 = a1 + data.l32.l; + b1 = b1 + a1; + a1 = a1 + data.l32.h; + b1 = b1 + a1; + dstmem64[i] = data.l64; + } + i++; + + data.l64 = srcmem64[i]; + a2 = a2 + data.l32.l; + b2 = b2 + a2; + a2 = a2 + data.l32.h; + b2 = b2 + a2; + dstmem64[i] = data.l64; + i++; + } + checksum->Set(a1, a2, b1, b2); + return true; +} + + +// C implementation of Adler memory crc. +bool WorkerThread::AdlerAddrCrcC(uint64 *srcmem64, + unsigned int size_in_bytes, + AdlerChecksum *checksum, + struct page_entry *pe) { + // Use this data wrapper to access memory with 64bit read/write. + datacast_t data; + unsigned int count = size_in_bytes / sizeof(data); + + if (count > ((1U) << 19)) { + // Size is too large, must be strictly less than 512 KB. + return false; + } + + uint64 a1 = 1; + uint64 a2 = 1; + uint64 b1 = 0; + uint64 b2 = 0; + + class Pattern *pattern = pe->pattern; + + unsigned int i = 0; + while (i < count) { + // Process 64 bits at a time. + if ((i & 0x7) == 0) { + data.l64 = srcmem64[i]; + uint64 src_tag = addr_to_tag(&srcmem64[i]); + // Check that tags match expected. + if (data.l64 != src_tag) + ReportTagError(&srcmem64[i], data.l64, src_tag); + + + data.l32.l = pattern->pattern(i << 1); + data.l32.h = pattern->pattern((i << 1) + 1); + a1 = a1 + data.l32.l; + b1 = b1 + a1; + a1 = a1 + data.l32.h; + b1 = b1 + a1; + + + } else { + data.l64 = srcmem64[i]; + a1 = a1 + data.l32.l; + b1 = b1 + a1; + a1 = a1 + data.l32.h; + b1 = b1 + a1; + } + i++; + + data.l64 = srcmem64[i]; + a2 = a2 + data.l32.l; + b2 = b2 + a2; + a2 = a2 + data.l32.h; + b2 = b2 + a2; + i++; + } + checksum->Set(a1, a2, b1, b2); + return true; +} + +// Copy a block of memory quickly, while keeping a CRC of the data. +// Result check if the CRC mismatches. +int WorkerThread::CrcCopyPage(struct page_entry *dstpe, + struct page_entry *srcpe) { + int errors = 0; + const int blocksize = 4096; + const int blockwords = blocksize / wordsize_; + int blocks = sat_->page_length() / blocksize; + + // Base addresses for memory copy + uint64 *targetmembase = static_cast(dstpe->addr); + uint64 *sourcemembase = static_cast(srcpe->addr); + // Remember the expected CRC + const AdlerChecksum *expectedcrc = srcpe->pattern->crc(); + + for (int currentblock = 0; currentblock < blocks; currentblock++) { + uint64 *targetmem = targetmembase + currentblock * blockwords; + uint64 *sourcemem = sourcemembase + currentblock * blockwords; + + AdlerChecksum crc; + if (tag_mode_) { + AdlerAddrMemcpyC(targetmem, sourcemem, blocksize, &crc, srcpe); + } else { + AdlerMemcpyC(targetmem, sourcemem, blocksize, &crc); + } + + // Investigate miscompares. + if (!crc.Equals(*expectedcrc)) { + logprintf(11, "Log: CrcCopyPage Falling through to slow compare, " + "CRC mismatch %s != %s\n", crc.ToHexString().c_str(), + expectedcrc->ToHexString().c_str()); + int errorcount = CheckRegion(sourcemem, + srcpe->pattern, + blocksize, + currentblock * blocksize, 0); + if (errorcount == 0) { + logprintf(0, "Log: CrcCopyPage CRC mismatch %s != %s, " + "but no miscompares found. Retrying with fresh data.\n", + crc.ToHexString().c_str(), + expectedcrc->ToHexString().c_str()); + if (!tag_mode_) { + // Copy the data originally read from this region back again. + // This data should have any corruption read originally while + // calculating the CRC. + memcpy(sourcemem, targetmem, blocksize); + errorcount = CheckRegion(sourcemem, + srcpe->pattern, + blocksize, + currentblock * blocksize, 0); + if (errorcount == 0) { + logprintf(0, "Process Error: CrcCopyPage CRC mismatch %s != %s, " + "but no miscompares found on second pass.\n", + crc.ToHexString().c_str(), + expectedcrc->ToHexString().c_str()); + } + } + } + errors += errorcount; + } + } + + // For odd length transfers, we should never hit this. + int leftovers = sat_->page_length() % blocksize; + if (leftovers) { + uint64 *targetmem = targetmembase + blocks * blockwords; + uint64 *sourcemem = sourcemembase + blocks * blockwords; + + errors += CheckRegion(sourcemem, + srcpe->pattern, + leftovers, + blocks * blocksize, 0); + int leftoverwords = leftovers / wordsize_; + for (int i = 0; i < leftoverwords; i++) { + targetmem[i] = sourcemem[i]; + } + } + + // Update pattern reference to reflect new contents. + dstpe->pattern = srcpe->pattern; + + // Clean clean clean the errors away. + if (errors) { + // TODO(nsanders): Maybe we should patch rather than fill? Filling may + // cause bad data to be propogated across the page. + FillPage(dstpe); + } + return errors; +} + + + +// Invert a block of memory quickly, traversing downwards. +int InvertThread::InvertPageDown(struct page_entry *srcpe) { + const int blocksize = 4096; + const int blockwords = blocksize / wordsize_; + int blocks = sat_->page_length() / blocksize; + + // Base addresses for memory copy + unsigned int *sourcemembase = static_cast(srcpe->addr); + + for (int currentblock = blocks-1; currentblock >= 0; currentblock--) { + unsigned int *sourcemem = sourcemembase + currentblock * blockwords; + for (int i = blockwords - 32; i >= 0; i -= 32) { + for (int index = i + 31; index >= i; --index) { + unsigned int actual = sourcemem[index]; + sourcemem[index] = ~actual; + } + OsLayer::FastFlush(&sourcemem[i]); + } + } + + return 0; +} + +// Invert a block of memory, traversing upwards. +int InvertThread::InvertPageUp(struct page_entry *srcpe) { + const int blocksize = 4096; + const int blockwords = blocksize / wordsize_; + int blocks = sat_->page_length() / blocksize; + + // Base addresses for memory copy + unsigned int *sourcemembase = static_cast(srcpe->addr); + + for (int currentblock = 0; currentblock < blocks; currentblock++) { + unsigned int *sourcemem = sourcemembase + currentblock * blockwords; + for (int i = 0; i < blockwords; i += 32) { + for (int index = i; index <= i + 31; ++index) { + unsigned int actual = sourcemem[index]; + sourcemem[index] = ~actual; + } + OsLayer::FastFlush(&sourcemem[i]); + } + } + return 0; +} + +// Copy a block of memory quickly, while keeping a CRC of the data. +// Result check if the CRC mismatches. Warm the CPU while running +int WorkerThread::CrcWarmCopyPage(struct page_entry *dstpe, + struct page_entry *srcpe) { + int errors = 0; + const int blocksize = 4096; + const int blockwords = blocksize / wordsize_; + int blocks = sat_->page_length() / blocksize; + + // Base addresses for memory copy + uint64 *targetmembase = static_cast(dstpe->addr); + uint64 *sourcemembase = static_cast(srcpe->addr); + // Remember the expected CRC + const AdlerChecksum *expectedcrc = srcpe->pattern->crc(); + + for (int currentblock = 0; currentblock < blocks; currentblock++) { + uint64 *targetmem = targetmembase + currentblock * blockwords; + uint64 *sourcemem = sourcemembase + currentblock * blockwords; + + AdlerChecksum crc; + if (tag_mode_) { + AdlerAddrMemcpyC(targetmem, sourcemem, blocksize, &crc, srcpe); + } else { + os_->AdlerMemcpyWarm(targetmem, sourcemem, blocksize, &crc); + } + + // Investigate miscompares. + if (!crc.Equals(*expectedcrc)) { + logprintf(11, "Log: CrcWarmCopyPage Falling through to slow compare, " + "CRC mismatch %s != %s\n", crc.ToHexString().c_str(), + expectedcrc->ToHexString().c_str()); + int errorcount = CheckRegion(sourcemem, + srcpe->pattern, + blocksize, + currentblock * blocksize, 0); + if (errorcount == 0) { + logprintf(0, "Log: CrcWarmCopyPage CRC mismatch %s != %s, " + "but no miscompares found. Retrying with fresh data.\n", + crc.ToHexString().c_str(), + expectedcrc->ToHexString().c_str()); + if (!tag_mode_) { + // Copy the data originally read from this region back again. + // This data should have any corruption read originally while + // calculating the CRC. + memcpy(sourcemem, targetmem, blocksize); + errorcount = CheckRegion(sourcemem, + srcpe->pattern, + blocksize, + currentblock * blocksize, 0); + if (errorcount == 0) { + logprintf(0, "Process Error: CrcWarmCopyPage CRC mismatch %s " + "!= %s, but no miscompares found on second pass.\n", + crc.ToHexString().c_str(), + expectedcrc->ToHexString().c_str()); + } + } + } + errors += errorcount; + } + } + + // For odd length transfers, we should never hit this. + int leftovers = sat_->page_length() % blocksize; + if (leftovers) { + uint64 *targetmem = targetmembase + blocks * blockwords; + uint64 *sourcemem = sourcemembase + blocks * blockwords; + + errors += CheckRegion(sourcemem, + srcpe->pattern, + leftovers, + blocks * blocksize, 0); + int leftoverwords = leftovers / wordsize_; + for (int i = 0; i < leftoverwords; i++) { + targetmem[i] = sourcemem[i]; + } + } + + // Update pattern reference to reflect new contents. + dstpe->pattern = srcpe->pattern; + + // Clean clean clean the errors away. + if (errors) { + // TODO(nsanders): Maybe we should patch rather than fill? Filling may + // cause bad data to be propogated across the page. + FillPage(dstpe); + } + return errors; +} + + + +// Memory check work loop. Execute until done, then exhaust pages. +int CheckThread::Work() { + struct page_entry pe; + int result = 1; + int64 loops = 0; + + logprintf(9, "Log: Starting Check thread %d\n", thread_num_); + + // We want to check all the pages, and + // stop when there aren't any left. + while (1) { + result &= sat_->GetValid(&pe); + if (!result) { + if (IsReadyToRunNoPause()) + logprintf(0, "Process Error: check_thread failed to pop pages, " + "bailing\n"); + else + result = 1; + break; + } + + // Do the result check. + CrcCheckPage(&pe); + + // Push pages back on the valid queue if we are still going, + // throw them out otherwise. + if (IsReadyToRunNoPause()) + result &= sat_->PutValid(&pe); + else + result &= sat_->PutEmpty(&pe); + if (!result) { + logprintf(0, "Process Error: check_thread failed to push pages, " + "bailing\n"); + break; + } + loops++; + } + + pages_copied_ = loops; + status_ = result; + logprintf(9, "Log: Completed %d: Check thread. Status %d, %d pages checked\n", + thread_num_, status_, pages_copied_); + return 1; +} + + +// Memory copy work loop. Execute until marked done. +int CopyThread::Work() { + struct page_entry src; + struct page_entry dst; + int result = 1; + int64 loops = 0; + + logprintf(9, "Log: Starting copy thread %d: cpu %x, mem %x\n", + thread_num_, cpu_mask_, tag_); + + while (IsReadyToRun()) { + // Pop the needed pages. + result &= sat_->GetValid(&src, tag_); + result &= sat_->GetEmpty(&dst, tag_); + if (!result) { + logprintf(0, "Process Error: copy_thread failed to pop pages, " + "bailing\n"); + break; + } + + // Force errors for unittests. + if (sat_->error_injection()) { + if (loops == 8) { + char *addr = reinterpret_cast(src.addr); + int offset = random() % sat_->page_length(); + addr[offset] = 0xba; + } + } + + // We can use memcpy, or CRC check while we copy. + if (sat_->warm()) { + CrcWarmCopyPage(&dst, &src); + } else if (sat_->strict()) { + CrcCopyPage(&dst, &src); + } else { + memcpy(dst.addr, src.addr, sat_->page_length()); + dst.pattern = src.pattern; + } + + result &= sat_->PutValid(&dst); + result &= sat_->PutEmpty(&src); + + // Copy worker-threads yield themselves at the end of each copy loop, + // to avoid threads from preempting each other in the middle of the inner + // copy-loop. Cooperations between Copy worker-threads results in less + // unnecessary cache thrashing (which happens when context-switching in the + // middle of the inner copy-loop). + YieldSelf(); + + if (!result) { + logprintf(0, "Process Error: copy_thread failed to push pages, " + "bailing\n"); + break; + } + loops++; + } + + pages_copied_ = loops; + status_ = result; + logprintf(9, "Log: Completed %d: Copy thread. Status %d, %d pages copied\n", + thread_num_, status_, pages_copied_); + return 1; +} + + + +// Memory invert work loop. Execute until marked done. +int InvertThread::Work() { + struct page_entry src; + int result = 1; + int64 loops = 0; + + logprintf(9, "Log: Starting invert thread %d\n", thread_num_); + + while (IsReadyToRun()) { + // Pop the needed pages. + result &= sat_->GetValid(&src); + if (!result) { + logprintf(0, "Process Error: invert_thread failed to pop pages, " + "bailing\n"); + break; + } + + if (sat_->strict()) + CrcCheckPage(&src); + + // For the same reason CopyThread yields itself (see YieldSelf comment + // in CopyThread::Work(), InvertThread yields itself after each invert + // operation to improve cooperation between different worker threads + // stressing the memory/cache. + InvertPageUp(&src); + YieldSelf(); + InvertPageDown(&src); + YieldSelf(); + InvertPageDown(&src); + YieldSelf(); + InvertPageUp(&src); + YieldSelf(); + + if (sat_->strict()) + CrcCheckPage(&src); + + result &= sat_->PutValid(&src); + if (!result) { + logprintf(0, "Process Error: invert_thread failed to push pages, " + "bailing\n"); + break; + } + loops++; + } + + pages_copied_ = loops * 2; + status_ = result; + logprintf(9, "Log: Completed %d: Copy thread. Status %d, %d pages copied\n", + thread_num_, status_, pages_copied_); + return 1; +} + + +// Set file name to use for File IO. +void FileThread::SetFile(const char *filename_init) { + filename_ = filename_init; + devicename_ = os_->FindFileDevice(filename_); +} + +// Open the file for access. +bool FileThread::OpenFile(int *pfile) { + int fd = open(filename_.c_str(), + O_RDWR | O_CREAT | O_SYNC | O_DIRECT, + 0644); + if (fd < 0) { + logprintf(0, "Process Error: Failed to create file %s!!\n", + filename_.c_str()); + pages_copied_ = 0; + status_ = 0; + return 0; + } + *pfile = fd; + return 1; +} + +// Close the file. +bool FileThread::CloseFile(int fd) { + close(fd); + return 1; +} + +// Check sector tagging. +bool FileThread::SectorTagPage(struct page_entry *src, int block) { + int page_length = sat_->page_length(); + struct FileThread::SectorTag *tag = + (struct FileThread::SectorTag *)(src->addr); + + // Tag each sector. + unsigned char magic = ((0xba + thread_num_) & 0xff); + for (int sec = 0; sec < page_length / 512; sec++) { + tag[sec].magic = magic; + tag[sec].block = block & 0xff; + tag[sec].sector = sec & 0xff; + tag[sec].pass = pass_ & 0xff; + } + return true; +} + +bool FileThread::WritePageToFile(int fd, struct page_entry *src) { + int page_length = sat_->page_length(); + // Fill the file with our data. + int64 size = write(fd, src->addr, page_length); + + if (size != page_length) { + os_->ErrorReport(devicename_.c_str(), "write-error", 1); + errorcount_++; + logprintf(0, "Block Error: file_thread failed to write, " + "bailing\n"); + return false; + } + return true; +} + +// Write the data to the file. +bool FileThread::WritePages(int fd) { + int strict = sat_->strict(); + + // Start fresh at beginning of file for each batch of pages. + lseek(fd, 0, SEEK_SET); + for (int i = 0; i < sat_->disk_pages(); i++) { + struct page_entry src; + if (!GetValidPage(&src)) + return false; + // Save expected pattern. + page_recs_[i].pattern = src.pattern; + page_recs_[i].src = src.addr; + + // Check data correctness. + if (strict) + CrcCheckPage(&src); + + SectorTagPage(&src, i); + + bool result = WritePageToFile(fd, &src); + + if (!PutEmptyPage(&src)) + return false; + + if (!result) + return false; + } + return true; +} + +// Copy data from file into memory block. +bool FileThread::ReadPageFromFile(int fd, struct page_entry *dst) { + int page_length = sat_->page_length(); + + // Do the actual read. + int64 size = read(fd, dst->addr, page_length); + if (size != page_length) { + os_->ErrorReport(devicename_.c_str(), "read-error", 1); + logprintf(0, "Block Error: file_thread failed to read, " + "bailing\n"); + errorcount_++; + return false; + } + return true; +} + +// Check sector tagging. +bool FileThread::SectorValidatePage(const struct PageRec &page, + struct page_entry *dst, int block) { + // Error injection. + static int calls = 0; + calls++; + + // Do sector tag compare. + int firstsector = -1; + int lastsector = -1; + bool badsector = false; + int page_length = sat_->page_length(); + + // Cast data block into an array of tagged sectors. + struct FileThread::SectorTag *tag = + (struct FileThread::SectorTag *)(dst->addr); + + sat_assert(sizeof(*tag) == 512); + + // Error injection. + if (sat_->error_injection()) { + if (calls == 2) { + for (int badsec = 8; badsec < 17; badsec++) + tag[badsec].pass = 27; + } + if (calls == 18) { + (static_cast(dst->addr))[27] = 0xbadda7a; + } + } + + // Check each sector for the correct tag we added earlier, + // then revert the tag to the to normal data pattern. + unsigned char magic = ((0xba + thread_num_) & 0xff); + for (int sec = 0; sec < page_length / 512; sec++) { + // Check magic tag. + if ((tag[sec].magic != magic) || + (tag[sec].block != (block & 0xff)) || + (tag[sec].sector != (sec & 0xff)) || + (tag[sec].pass != (pass_ & 0xff))) { + // Offset calculation for tag location. + int offset = sec * sizeof(SectorTag); + if (tag[sec].block != (block & 0xff)) + offset += 1 * sizeof(uint8); + else if (tag[sec].sector != (sec & 0xff)) + offset += 2 * sizeof(uint8); + else if (tag[sec].pass != (pass_ & 0xff)) + offset += 3 * sizeof(uint8); + + // Run sector tag error through diagnoser for logging and reporting. + errorcount_ += 1; + os_->error_diagnoser_->AddHDDSectorTagError(devicename_, tag[sec].block, + offset, + tag[sec].sector, + page.src, page.dst); + + logprintf(5, "Sector Error: Sector tag @ 0x%x, pass %d/%d. " + "sec %x/%x, block %d/%d, magic %x/%x, File: %s \n", + block * page_length + 512 * sec, + (pass_ & 0xff), (unsigned int)tag[sec].pass, + sec, (unsigned int)tag[sec].sector, + block, (unsigned int)tag[sec].block, + magic, (unsigned int)tag[sec].magic, + filename_.c_str()); + + // Keep track of first and last bad sector. + if (firstsector == -1) + firstsector = (block * page_length / 512) + sec; + lastsector = (block * page_length / 512) + sec; + badsector = true; + } + // Patch tag back to proper pattern. + unsigned int *addr = (unsigned int *)(&tag[sec]); + *addr = dst->pattern->pattern(512 * sec / sizeof(*addr)); + } + + // If we found sector errors: + if (badsector == true) { + logprintf(5, "Log: file sector miscompare at offset %x-%x. File: %s\n", + firstsector * 512, + ((lastsector + 1) * 512) - 1, + filename_.c_str()); + + // Either exit immediately, or patch the data up and continue. + if (sat_->stop_on_error()) { + exit(1); + } else { + // Patch up bad pages. + for (int block = (firstsector * 512) / page_length; + block <= (lastsector * 512) / page_length; + block++) { + unsigned int *memblock = static_cast(dst->addr); + int length = page_length / wordsize_; + for (int i = 0; i < length; i++) { + memblock[i] = dst->pattern->pattern(i); + } + } + } + } + return true; +} + + + +// Get memory for an incoming data transfer.. +bool FileThread::PagePrepare() { + // We can only do direct IO to SAT pages if it is normal mem. + page_io_ = os_->normal_mem(); + + // Init a local buffer if we need it. + if (!page_io_) { + local_page_ = static_cast(memalign(512, sat_->page_length())); + if (!local_page_) { + logprintf(0, "Process Error: disk thread memalign returned 0\n"); + status_ += 1; + return false; + } + } + return true; +} + + +// Remove memory allocated for data transfer. +bool FileThread::PageTeardown() { + // Free a local buffer if we need to. + if (!page_io_) { + free(local_page_); + } + return true; +} + + + +// Get memory for an incoming data transfer.. +bool FileThread::GetEmptyPage(struct page_entry *dst) { + if (page_io_) { + if (!sat_->GetEmpty(dst)) + return false; + } else { + dst->addr = local_page_; + dst->offset = 0; + dst->pattern = 0; + } + return true; +} + +// Get memory for an outgoing data transfer.. +bool FileThread::GetValidPage(struct page_entry *src) { + struct page_entry tmp; + if (!sat_->GetValid(&tmp)) + return false; + if (page_io_) { + *src = tmp; + return true; + } else { + src->addr = local_page_; + src->offset = 0; + CrcCopyPage(src, &tmp); + if (!sat_->PutValid(&tmp)) + return false; + } + return true; +} + + +// Throw out a used empty page. +bool FileThread::PutEmptyPage(struct page_entry *src) { + if (page_io_) { + if (!sat_->PutEmpty(src)) + return false; + } + return true; +} + +// Throw out a used, filled page. +bool FileThread::PutValidPage(struct page_entry *src) { + if (page_io_) { + if (!sat_->PutValid(src)) + return false; + } + return true; +} + + + +// Copy data from file into memory blocks. +bool FileThread::ReadPages(int fd) { + int page_length = sat_->page_length(); + int strict = sat_->strict(); + int result = 1; + + + // Read our data back out of the file, into it's new location. + lseek(fd, 0, SEEK_SET); + for (int i = 0; i < sat_->disk_pages(); i++) { + struct page_entry dst; + if (!GetEmptyPage(&dst)) + return false; + // Retrieve expected pattern. + dst.pattern = page_recs_[i].pattern; + // Update page recordpage record. + page_recs_[i].dst = dst.addr; + + // Read from the file into destination page. + if (!ReadPageFromFile(fd, &dst)) { + PutEmptyPage(&dst); + return false; + } + + SectorValidatePage(page_recs_[i], &dst, i); + + // Ensure that the transfer ended up with correct data. + if (strict) { + // Record page index currently CRC checked. + crc_page_ = i; + int errors = CrcCheckPage(&dst); + if (errors) { + logprintf(5, "Log: file miscompare at block %d, " + "offset %x-%x. File: %s\n", + i, i * page_length, ((i + 1) * page_length) - 1, + filename_.c_str()); + result = false; + } + crc_page_ = -1; + errorcount_ += errors; + } + if (!PutValidPage(&dst)) + return false; + } + return result; +} + + +// File IO work loop. Execute until marked done. +int FileThread::Work() { + int result = 1; + int fileresult = 1; + int64 loops = 0; + + logprintf(9, "Log: Starting file thread %d, file %s, device %s\n", + thread_num_, + filename_.c_str(), + devicename_.c_str()); + + if (!PagePrepare()) + return 0; + + // Open the data IO file. + int fd = 0; + if (!OpenFile(&fd)) + return 0; + + pass_ = 0; + + // Load patterns into page records. + page_recs_ = new struct PageRec[sat_->disk_pages()]; + for (int i = 0; i < sat_->disk_pages(); i++) { + page_recs_[i].pattern = new struct Pattern(); + } + + // Loop until done. + while (IsReadyToRun()) { + // Do the file write. + if (!(fileresult &= WritePages(fd))) + break; + + // Do the file read. + if (!(fileresult &= ReadPages(fd))) + break; + + loops++; + pass_ = loops; + } + + pages_copied_ = loops * sat_->disk_pages(); + status_ = result; + + // Clean up. + CloseFile(fd); + PageTeardown(); + + logprintf(9, "Log: Completed %d: file thread status %d, %d pages copied\n", + thread_num_, status_, pages_copied_); + return 1; +} + +bool NetworkThread::IsNetworkStopSet() { + return !IsReadyToRunNoPause(); +} + +bool NetworkSlaveThread::IsNetworkStopSet() { + // This thread has no completion status. + // It finishes whever there is no more data to be + // passed back. + return true; +} + +// Set ip name to use for Network IO. +void NetworkThread::SetIP(const char *ipaddr_init) { + strncpy(ipaddr_, ipaddr_init, 256); +} + +// Create a socket. +// Return 0 on error. +bool NetworkThread::CreateSocket(int *psocket) { + int sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock == -1) { + logprintf(0, "Process Error: Cannot open socket\n"); + pages_copied_ = 0; + status_ = 0; + return false; + } + *psocket = sock; + return true; +} + +// Close the socket. +bool NetworkThread::CloseSocket(int sock) { + close(sock); + return true; +} + +// Initiate the tcp connection. +bool NetworkThread::Connect(int sock) { + struct sockaddr_in dest_addr; + dest_addr.sin_family = AF_INET; + dest_addr.sin_port = htons(kNetworkPort); + memset(&(dest_addr.sin_zero), '\0', sizeof(dest_addr.sin_zero)); + + // Translate dot notation to u32. + if (inet_aton(ipaddr_, &dest_addr.sin_addr) == 0) { + logprintf(0, "Process Error: Cannot resolve %s\n", ipaddr_); + pages_copied_ = 0; + status_ = 0; + return false; + } + + if (-1 == connect(sock, reinterpret_cast(&dest_addr), + sizeof(struct sockaddr))) { + logprintf(0, "Process Error: Cannot connect %s\n", ipaddr_); + pages_copied_ = 0; + status_ = 0; + return false; + } + return true; +} + +// Initiate the tcp connection. +bool NetworkListenThread::Listen() { + struct sockaddr_in sa; + + memset(&(sa.sin_zero), '\0', sizeof(sa.sin_zero)); + + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = INADDR_ANY; + sa.sin_port = htons(kNetworkPort); + + if (-1 == bind(sock_, (struct sockaddr*)&sa, sizeof(struct sockaddr))) { + char buf[256]; + sat_strerror(errno, buf, sizeof(buf)); + logprintf(0, "Process Error: Cannot bind socket: %s\n", buf); + pages_copied_ = 0; + status_ = 0; + return false; + } + listen(sock_, 3); + return true; +} + +// Wait for a connection from a network traffic generation thread. +bool NetworkListenThread::Wait() { + fd_set rfds; + struct timeval tv; + int retval; + + // Watch sock_ to see when it has input. + FD_ZERO(&rfds); + FD_SET(sock_, &rfds); + // Wait up to five seconds. + tv.tv_sec = 5; + tv.tv_usec = 0; + + retval = select(sock_ + 1, &rfds, NULL, NULL, &tv); + + return (retval > 0); +} + +// Wait for a connection from a network traffic generation thread. +bool NetworkListenThread::GetConnection(int *pnewsock) { + struct sockaddr_in sa; + socklen_t size = sizeof(struct sockaddr_in); + + int newsock = accept(sock_, reinterpret_cast(&sa), &size); + if (newsock < 0) { + logprintf(0, "Process Error: Did not receive connection\n"); + pages_copied_ = 0; + status_ = 0; + return false; + } + *pnewsock = newsock; + return true; +} + +bool NetworkThread::SendPage(int sock, struct page_entry *src) { + int page_length = sat_->page_length(); + char *address = static_cast(src->addr); + + // Send our data over the network. + int size = page_length; + while (size) { + int transferred = send(sock, address + (page_length - size), size, 0); + if ((transferred == 0) || (transferred == -1)) { + if (!IsNetworkStopSet()) { + char buf[256] = ""; + sat_strerror(errno, buf, sizeof(buf)); + logprintf(0, "Process Error: Thread %d, " + "Network write failed, bailing. (%s)\n", + thread_num_, buf); + } + return false; + } + size = size - transferred; + } + return true; +} + + +bool NetworkThread::ReceivePage(int sock, struct page_entry *dst) { + int page_length = sat_->page_length(); + char *address = static_cast(dst->addr); + + // Maybe we will get our data back again, maybe not. + int size = page_length; + while (size) { + int transferred = recv(sock, address + (page_length - size), size, 0); + if ((transferred == 0) || (transferred == -1)) { + // Typically network slave thread should exit as network master + // thread stops sending data. + if (IsNetworkStopSet()) { + int err = errno; + if (transferred == 0 && err == 0) { + // Two system setups will not sync exactly, + // allow early exit, but log it. + logprintf(0, "Log: Net thread did not recieve any data, exitting.\n"); + } else { + char buf[256] = ""; + sat_strerror(err, buf, sizeof(buf)); + // Print why we failed. + logprintf(0, "Process Error: Thread %d, " + "Network read failed, bailing (%s).\n", + thread_num_, buf); + // Print arguments and results. + logprintf(0, "Log: recv(%d, address %x, size %x, 0) == %x, err %d\n", + sock, address + (page_length - size), + size, transferred, err); + if ((transferred == 0) && + (page_length - size < 512) && + (page_length - size > 0)) { + // Print null terminated data received, to see who's been + // sending us supicious unwanted data. + address[page_length - size] = 0; + logprintf(0, "Log: received %d bytes: '%s'\n", + page_length - size, address); + } + } + } + return false; + } + size = size - transferred; + } + return true; +} + + +// Network IO work loop. Execute until marked done. +int NetworkThread::Work() { + logprintf(9, "Log: Starting network thread %d, ip %s\n", + thread_num_, + ipaddr_); + + // Make a socket. + int sock = 0; + if (!CreateSocket(&sock)) + return 0; + + // Network IO loop requires network slave thread to have already initialized. + // We will sleep here for awhile to ensure that the slave thread will be + // listening by the time we connect. + // Sleep for 15 seconds. + sat_sleep(15); + logprintf(9, "Log: Starting execution of network thread %d, ip %s\n", + thread_num_, + ipaddr_); + + + // Connect to a slave thread. + if (!Connect(sock)) + return 0; + + // Loop until done. + int result = 1; + int strict = sat_->strict(); + int64 loops = 0; + while (IsReadyToRun()) { + struct page_entry src; + struct page_entry dst; + result &= sat_->GetValid(&src); + result &= sat_->GetEmpty(&dst); + if (!result) { + logprintf(0, "Process Error: net_thread failed to pop pages, " + "bailing\n"); + break; + } + + // Check data correctness. + if (strict) + CrcCheckPage(&src); + + // Do the network write. + if (!(result &= SendPage(sock, &src))) + break; + + // Update pattern reference to reflect new contents. + dst.pattern = src.pattern; + + // Do the network read. + if (!(result &= ReceivePage(sock, &dst))) + break; + + // Ensure that the transfer ended up with correct data. + if (strict) + CrcCheckPage(&dst); + + // Return all of our pages to the queue. + result &= sat_->PutValid(&dst); + result &= sat_->PutEmpty(&src); + if (!result) { + logprintf(0, "Process Error: net_thread failed to push pages, " + "bailing\n"); + break; + } + loops++; + } + + pages_copied_ = loops; + status_ = result; + + // Clean up. + CloseSocket(sock); + + logprintf(9, "Log: Completed %d: network thread status %d, " + "%d pages copied\n", + thread_num_, status_, pages_copied_); + return 1; +} + +// Spawn slave threads for incoming connections. +bool NetworkListenThread::SpawnSlave(int newsock, int threadid) { + logprintf(12, "Log: Listen thread spawning slave\n"); + + // Spawn slave thread, to reflect network traffic back to sender. + ChildWorker *child_worker = new ChildWorker; + child_worker->thread.SetSock(newsock); + child_worker->thread.InitThread(threadid, sat_, os_, patternlist_, + &child_worker->status); + child_worker->status.Initialize(); + child_worker->thread.SpawnThread(); + child_workers_.push_back(child_worker); + + return true; +} + +// Reap slave threads. +bool NetworkListenThread::ReapSlaves() { + bool result = true; + // Gather status and reap threads. + logprintf(12, "Log: Joining all outstanding threads\n"); + + for (int i = 0; i < child_workers_.size(); i++) { + NetworkSlaveThread& child_thread = child_workers_[i]->thread; + logprintf(12, "Log: Joining slave thread %d\n", i); + child_thread.JoinThread(); + if (child_thread.GetStatus() != 1) { + logprintf(0, "Process Error: Slave Thread %d failed with status %d\n", i, + child_thread.GetStatus()); + result = false; + } + errorcount_ += child_thread.GetErrorCount(); + logprintf(9, "Log: Slave Thread %d found %lld miscompares\n", i, + child_thread.GetErrorCount()); + pages_copied_ += child_thread.GetPageCount(); + } + + return result; +} + +// Network listener IO work loop. Execute until marked done. +int NetworkListenThread::Work() { + int result = 1; + logprintf(9, "Log: Starting network listen thread %d\n", + thread_num_); + + // Make a socket. + sock_ = 0; + if (!CreateSocket(&sock_)) + return 0; + logprintf(9, "Log: Listen thread created sock\n"); + + // Allows incoming connections to be queued up by socket library. + int newsock = 0; + Listen(); + logprintf(12, "Log: Listen thread waiting for incoming connections\n"); + + // Wait on incoming connections, and spawn worker threads for them. + int threadcount = 0; + while (IsReadyToRun()) { + // Poll for connections that we can accept(). + if (Wait()) { + // Accept those connections. + logprintf(12, "Log: Listen thread found incoming connection\n"); + if (GetConnection(&newsock)) { + SpawnSlave(newsock, threadcount); + threadcount++; + } + } + } + + // Gather status and join spawned threads. + ReapSlaves(); + + // Delete the child workers. + for (ChildVector::iterator it = child_workers_.begin(); + it != child_workers_.end(); ++it) { + (*it)->status.Destroy(); + delete *it; + } + child_workers_.clear(); + + CloseSocket(sock_); + + status_ = result; + logprintf(9, + "Log: Completed %d: network listen thread status %d, " + "%d pages copied\n", + thread_num_, status_, pages_copied_); + return 1; +} + +// Set network reflector socket struct. +void NetworkSlaveThread::SetSock(int sock) { + sock_ = sock; +} + +// Network reflector IO work loop. Execute until marked done. +int NetworkSlaveThread::Work() { + logprintf(9, "Log: Starting network slave thread %d\n", + thread_num_); + + // Verify that we have a socket. + int sock = sock_; + if (!sock) + return 0; + + // Loop until done. + int result = 1; + int64 loops = 0; + // Init a local buffer for storing data. + void *local_page = static_cast(memalign(512, sat_->page_length())); + if (!local_page) { + logprintf(0, "Process Error: Net Slave thread memalign returned 0\n"); + status_ += 1; + return 0; + } + + struct page_entry page; + page.addr = local_page; + + // This thread will continue to run as long as the thread on the other end of + // the socket is still sending and receiving data. + while (1) { + // Do the network read. + if (!ReceivePage(sock, &page)) + break; + + // Do the network write. + if (!SendPage(sock, &page)) + break; + + loops++; + } + + pages_copied_ = loops; + status_ = result; + + // Clean up. + CloseSocket(sock); + + logprintf(9, + "Log: Completed %d: network slave thread status %d, " + "%d pages copied\n", + thread_num_, status_, pages_copied_); + return result; +} + +// Thread work loop. Execute until marked finished. +int ErrorPollThread::Work() { + logprintf(9, "Log: Starting system error poll thread %d\n", thread_num_); + + // This calls a generic error polling function in the Os abstraction layer. + do { + errorcount_ += os_->ErrorPoll(); + os_->ErrorWait(); + } while (IsReadyToRun()); + + logprintf(9, "Log: Finished system error poll thread %d: %d errors\n", + thread_num_, errorcount_); + status_ = 1; + return 1; +} + +// Worker thread to heat up CPU. +int CpuStressThread::Work() { + logprintf(9, "Log: Starting CPU stress thread %d\n", thread_num_); + + do { + // Run ludloff's platform/CPU-specific assembly workload. + os_->CpuStressWorkload(); + YieldSelf(); + } while (IsReadyToRun()); + + logprintf(9, "Log: Finished CPU stress thread %d:\n", + thread_num_); + status_ = 1; + return 1; +} + +CpuCacheCoherencyThread::CpuCacheCoherencyThread(cc_cacheline_data *data, + int cacheline_count, + int thread_num, + int inc_count) { + cc_cacheline_data_ = data; + cc_cacheline_count_ = cacheline_count; + cc_thread_num_ = thread_num; + cc_inc_count_ = inc_count; +} + +// Worked thread to test the cache coherency of the CPUs +int CpuCacheCoherencyThread::Work() { + logprintf(9, "Log: Starting the Cache Coherency thread %d\n", + cc_thread_num_); + uint64 time_start, time_end; + struct timeval tv; + + unsigned int seed = static_cast(gettid()); + gettimeofday(&tv, NULL); // Get the timestamp before increments. + time_start = tv.tv_sec * 1000000ULL + tv.tv_usec; + + uint64 total_inc = 0; // Total increments done by the thread. + while (IsReadyToRun()) { + for (int i = 0; i < cc_inc_count_; i++) { + // Choose a datastructure in random and increment the appropriate + // member in that according to the offset (which is the same as the + // thread number. + int r = rand_r(&seed); + r = cc_cacheline_count_ * (r / (RAND_MAX + 1.0)); + // Increment the member of the randomely selected structure. + (cc_cacheline_data_[r].num[cc_thread_num_])++; + } + + total_inc += cc_inc_count_; + + // Calculate if the local counter matches with the global value + // in all the cache line structures for this particular thread. + int cc_global_num = 0; + for (int cline_num = 0; cline_num < cc_cacheline_count_; cline_num++) { + cc_global_num += cc_cacheline_data_[cline_num].num[cc_thread_num_]; + // Reset the cachline member's value for the next run. + cc_cacheline_data_[cline_num].num[cc_thread_num_] = 0; + } + if (sat_->error_injection()) + cc_global_num = -1; + + if (cc_global_num != cc_inc_count_) { + errorcount_++; + logprintf(0, "Hardware Error: global(%d) and local(%d) do not match\n", + cc_global_num, cc_inc_count_); + } + } + gettimeofday(&tv, NULL); // Get the timestamp at the end. + time_end = tv.tv_sec * 1000000ULL + tv.tv_usec; + + uint64 us_elapsed = time_end - time_start; + // inc_rate is the no. of increments per second. + double inc_rate = total_inc * 1e6 / us_elapsed; + + logprintf(4, "Stats: CC Thread(%d): Time=%llu us," + " Increments=%llu, Increments/sec = %.6lf\n", + cc_thread_num_, us_elapsed, total_inc, inc_rate); + logprintf(9, "Log: Finished CPU Cache Coherency thread %d:\n", + cc_thread_num_); + status_ = 1; + return 1; +} + +DiskThread::DiskThread(DiskBlockTable *block_table) { + read_block_size_ = kSectorSize; // default 1 sector (512 bytes) + write_block_size_ = kSectorSize; // this assumes read and write block size + // are the same + segment_size_ = -1; // use the entire disk as one segment + cache_size_ = 16 * 1024 * 1024; // assume 16MiB cache by default + // Use a queue such that 3/2 times as much data as the cache can hold + // is written before it is read so that there is little chance the read + // data is in the cache. + queue_size_ = ((cache_size_ / write_block_size_) * 3) / 2; + blocks_per_segment_ = 32; + + read_threshold_ = 100000; // 100ms is a reasonable limit for + write_threshold_ = 100000; // reading/writing a sector + + read_timeout_ = 5000000; // 5 seconds should be long enough for a + write_timeout_ = 5000000; // timout for reading/writing + + device_sectors_ = 0; + non_destructive_ = 0; + + aio_ctx_ = 0; + block_table_ = block_table; + update_block_table_ = 1; +} + +DiskThread::~DiskThread() { +} + +// Set filename for device file (in /dev). +void DiskThread::SetDevice(const char *device_name) { + device_name_ = device_name; +} + +// Set various parameters that control the behaviour of the test. +// -1 is used as a sentinel value on each parameter (except non_destructive) +// to indicate that the parameter not be set. +bool DiskThread::SetParameters(int read_block_size, + int write_block_size, + int64 segment_size, + int64 cache_size, + int blocks_per_segment, + int64 read_threshold, + int64 write_threshold, + int non_destructive) { + if (read_block_size != -1) { + // Blocks must be aligned to the disk's sector size. + if (read_block_size % kSectorSize != 0) { + logprintf(0, "Process Error: Block size must be a multiple of %d " + "(thread %d).\n", kSectorSize, thread_num_); + return false; + } + + read_block_size_ = read_block_size; + } + + if (write_block_size != -1) { + // Write blocks must be aligned to the disk's sector size and to the + // block size. + if (write_block_size % kSectorSize != 0) { + logprintf(0, "Process Error: Write block size must be a multiple " + "of %d (thread %d).\n", kSectorSize, thread_num_); + return false; + } + if (write_block_size % read_block_size_ != 0) { + logprintf(0, "Process Error: Write block size must be a multiple " + "of the read block size, which is %d (thread %d).\n", + read_block_size_, thread_num_); + return false; + } + + write_block_size_ = write_block_size; + + } else { + // Make sure write_block_size_ is still valid. + if (read_block_size_ > write_block_size_) { + logprintf(5, "Log: Assuming write block size equal to read block size, " + "which is %d (thread %d).\n", read_block_size_, + thread_num_); + write_block_size_ = read_block_size_; + } else { + if (write_block_size_ % read_block_size_ != 0) { + logprintf(0, "Process Error: Write block size (defined as %d) must " + "be a multiple of the read block size, which is %d " + "(thread %d).\n", write_block_size_, read_block_size_, + thread_num_); + return false; + } + } + } + + if (cache_size != -1) { + cache_size_ = cache_size; + } + + if (blocks_per_segment != -1) { + if (blocks_per_segment <= 0) { + logprintf(0, "Process Error: Blocks per segment must be greater than " + "zero.\n (thread %d)", thread_num_); + return false; + } + + blocks_per_segment_ = blocks_per_segment; + } + + if (read_threshold != -1) { + if (read_threshold <= 0) { + logprintf(0, "Process Error: Read threshold must be greater than " + "zero (thread %d).\n", thread_num_); + return false; + } + + read_threshold_ = read_threshold; + } + + if (write_threshold != -1) { + if (write_threshold <= 0) { + logprintf(0, "Process Error: Write threshold must be greater than " + "zero (thread %d).\n", thread_num_); + return false; + } + + write_threshold_ = write_threshold; + } + + if (segment_size != -1) { + // Segments must be aligned to the disk's sector size. + if (segment_size % kSectorSize != 0) { + logprintf(0, "Process Error: Segment size must be a multiple of %d" + " (thread %d).\n", kSectorSize, thread_num_); + return false; + } + + segment_size_ = segment_size / kSectorSize; + } + + non_destructive_ = non_destructive; + + // Having a queue of 150% of blocks that will fit in the disk's cache + // should be enough to force out the oldest block before it is read and hence, + // making sure the data comes form the disk and not the cache. + queue_size_ = ((cache_size_ / write_block_size_) * 3) / 2; + // Updating DiskBlockTable parameters + if (update_block_table_) { + block_table_->SetParameters(kSectorSize, write_block_size_, + device_sectors_, segment_size_, + device_name_); + } + return true; +} + +bool DiskThread::OpenDevice(int *pfile) { + int fd = open(device_name_.c_str(), + O_RDWR | O_SYNC | O_DIRECT | O_LARGEFILE, + 0); + if (fd < 0) { + logprintf(0, "Process Error: Failed to open device %s (thread %d)!!\n", + device_name_.c_str(), thread_num_); + return false; + } + *pfile = fd; + + return GetDiskSize(fd); +} + +// Retrieves the size (in bytes) of the disk/file. +bool DiskThread::GetDiskSize(int fd) { + struct stat device_stat; + if (fstat(fd, &device_stat) == -1) { + logprintf(0, "Process Error: Unable to fstat disk %s (thread %d).\n", + device_name_.c_str(), thread_num_); + return false; + } + + // For a block device, an ioctl is needed to get the size since the size + // of the device file (i.e. /dev/sdb) is 0. + if (S_ISBLK(device_stat.st_mode)) { + uint64 block_size = 0; + + if (ioctl(fd, BLKGETSIZE64, &block_size) == -1) { + logprintf(0, "Process Error: Unable to ioctl disk %s (thread %d).\n", + device_name_.c_str(), thread_num_); + return false; + } + + // If an Elephant is initialized with status DEAD its size will be zero. + if (block_size == 0) { + os_->ErrorReport(device_name_.c_str(), "device-size-zero", 1); + ++errorcount_; + status_ = 1; // Avoid a procedural error. + return false; + } + + device_sectors_ = block_size / kSectorSize; + + } else if (S_ISREG(device_stat.st_mode)) { + device_sectors_ = device_stat.st_size / kSectorSize; + + } else { + logprintf(0, "Process Error: %s is not a regular file or block " + "device (thread %d).\n", device_name_.c_str(), + thread_num_); + return false; + } + + logprintf(12, "Log: Device sectors: %lld on disk %s (thread %d).\n", + device_sectors_, device_name_.c_str(), thread_num_); + + if (update_block_table_) { + block_table_->SetParameters(kSectorSize, write_block_size_, + device_sectors_, segment_size_, + device_name_); + } + + return true; +} + +bool DiskThread::CloseDevice(int fd) { + close(fd); + return true; +} + +// Return the time in microseconds. +int64 DiskThread::GetTime() { + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec * 1000000 + tv.tv_usec; +} + +bool DiskThread::DoWork(int fd) { + int64 block_num = 0; + blocks_written_ = 0; + blocks_read_ = 0; + int64 num_segments; + + if (segment_size_ == -1) { + num_segments = 1; + } else { + num_segments = device_sectors_ / segment_size_; + if (device_sectors_ % segment_size_ != 0) + num_segments++; + } + + // Disk size should be at least 3x cache size. See comment later for + // details. + sat_assert(device_sectors_ * kSectorSize > 3 * cache_size_); + + // This disk test works by writing blocks with a certain pattern to + // disk, then reading them back and verifying it against the pattern + // at a later time. A failure happens when either the block cannot + // be written/read or when the read block is different than what was + // written. If a block takes too long to write/read, then a warning + // is given instead of an error since taking too long is not + // necessarily an error. + // + // To prevent the read blocks from coming from the disk cache, + // enough blocks are written before read such that a block would + // be ejected from the disk cache by the time it is read. + // + // TODO(amistry): Implement some sort of read/write throttling. The + // flood of asynchronous I/O requests when a drive is + // unplugged is causing the application and kernel to + // become unresponsive. + + while (IsReadyToRun()) { + // Write blocks to disk. + logprintf(16, "Write phase for disk %s (thread %d).\n", + device_name_.c_str(), thread_num_); + while (IsReadyToRunNoPause() && + in_flight_sectors_.size() < queue_size_ + 1) { + // Confine testing to a particular segment of the disk. + int64 segment = (block_num / blocks_per_segment_) % num_segments; + if (block_num % blocks_per_segment_ == 0) { + logprintf(20, "Log: Starting to write segment %lld out of " + "%lld on disk %s (thread %d).\n", + segment, num_segments, device_name_.c_str(), + thread_num_); + } + block_num++; + + BlockData *block = block_table_->GetUnusedBlock(segment); + + // If an unused sequence of sectors could not be found, skip to the + // next block to process. Soon, a new segment will come and new + // sectors will be able to be allocated. This effectively puts a + // minumim on the disk size at 3x the stated cache size, or 48MiB + // if a cache size is not given (since the cache is set as 16MiB + // by default). Given that todays caches are at the low MiB range + // and drive sizes at the mid GB, this shouldn't pose a problem. + // The 3x minimum comes from the following: + // 1. In order to allocate 'y' blocks from a segment, the + // segment must contain at least 2y blocks or else an + // allocation may not succeed. + // 2. Assume the entire disk is one segment. + // 3. A full write phase consists of writing blocks corresponding to + // 3/2 cache size. + // 4. Therefore, the one segment must have 2 * 3/2 * cache + // size worth of blocks = 3 * cache size worth of blocks + // to complete. + // In non-destructive mode, don't write anything to disk. + if (!non_destructive_) { + if (!WriteBlockToDisk(fd, block)) { + block_table_->RemoveBlock(block); + continue; + } + } + + block->SetBlockAsInitialized(); + + blocks_written_++; + in_flight_sectors_.push(block); + } + + // Verify blocks on disk. + logprintf(20, "Read phase for disk %s (thread %d).\n", + device_name_.c_str(), thread_num_); + while (IsReadyToRunNoPause() && !in_flight_sectors_.empty()) { + BlockData *block = in_flight_sectors_.front(); + in_flight_sectors_.pop(); + ValidateBlockOnDisk(fd, block); + block_table_->RemoveBlock(block); + blocks_read_++; + } + } + + pages_copied_ = blocks_written_ + blocks_read_; + return true; +} + +// Do an asynchronous disk I/O operation. +bool DiskThread::AsyncDiskIO(IoOp op, int fd, void *buf, int64 size, + int64 offset, int64 timeout) { + // Use the Linux native asynchronous I/O interface for reading/writing. + // A read/write consists of three basic steps: + // 1. create an io context. + // 2. prepare and submit an io request to the context + // 3. wait for an event on the context. + + struct { + const int opcode; + const char *op_str; + const char *error_str; + } operations[2] = { + { IOCB_CMD_PREAD, "read", "disk-read-error" }, + { IOCB_CMD_PWRITE, "write", "disk-write-error" } + }; + + struct iocb cb; + memset(&cb, 0, sizeof(cb)); + + cb.aio_fildes = fd; + cb.aio_lio_opcode = operations[op].opcode; + cb.aio_buf = (__u64)buf; + cb.aio_nbytes = size; + cb.aio_offset = offset; + + struct iocb *cbs[] = { &cb }; + if (io_submit(aio_ctx_, 1, cbs) != 1) { + logprintf(0, "Process Error: Unable to submit async %s " + "on disk %s (thread %d).\n", + operations[op].op_str, device_name_.c_str(), + thread_num_); + return false; + } + + struct io_event event; + memset(&event, 0, sizeof(event)); + struct timespec tv; + tv.tv_sec = timeout / 1000000; + tv.tv_nsec = (timeout % 1000000) * 1000; + if (io_getevents(aio_ctx_, 1, 1, &event, &tv) != 1) { + // A ctrl-c from the keyboard will cause io_getevents to fail with an + // EINTR error code. This is not an error and so don't treat it as such, + // but still log it. + if (errno == EINTR) { + logprintf(5, "Log: %s interrupted on disk %s (thread %d).\n", + operations[op].op_str, device_name_.c_str(), + thread_num_); + } else { + os_->ErrorReport(device_name_.c_str(), operations[op].error_str, 1); + errorcount_ += 1; + logprintf(0, "Hardware Error: Timeout doing async %s to sectors " + "starting at %lld on disk %s (thread %d).\n", + operations[op].op_str, offset / kSectorSize, + device_name_.c_str(), thread_num_); + } + + // Don't bother checking return codes since io_cancel seems to always fail. + // Since io_cancel is always failing, destroying and recreating an I/O + // context is a workaround for canceling an in-progress I/O operation. + // TODO(amistry): Find out why io_cancel isn't working and make it work. + io_cancel(aio_ctx_, &cb, &event); + io_destroy(aio_ctx_); + aio_ctx_ = 0; + if (io_setup(5, &aio_ctx_)) { + logprintf(0, "Process Error: Unable to create aio context on disk %s" + " (thread %d).\n", + device_name_.c_str(), thread_num_); + } + + return false; + } + + // event.res contains the number of bytes written/read or + // error if < 0, I think. + if (event.res != size) { + errorcount_++; + os_->ErrorReport(device_name_.c_str(), operations[op].error_str, 1); + + if (event.res < 0) { + switch (event.res) { + case -EIO: + logprintf(0, "Hardware Error: Low-level I/O error while doing %s to " + "sectors starting at %lld on disk %s (thread %d).\n", + operations[op].op_str, offset / kSectorSize, + device_name_.c_str(), thread_num_); + break; + default: + logprintf(0, "Hardware Error: Unknown error while doing %s to " + "sectors starting at %lld on disk %s (thread %d).\n", + operations[op].op_str, offset / kSectorSize, + device_name_.c_str(), thread_num_); + } + } else { + logprintf(0, "Hardware Error: Unable to %s to sectors starting at " + "%lld on disk %s (thread %d).\n", + operations[op].op_str, offset / kSectorSize, + device_name_.c_str(), thread_num_); + } + return false; + } + + return true; +} + +// Write a block to disk. +bool DiskThread::WriteBlockToDisk(int fd, BlockData *block) { + memset(block_buffer_, 0, block->GetSize()); + + // Fill block buffer with a pattern + struct page_entry pe; + if (!sat_->GetValid(&pe)) { + // Even though a valid page could not be obatined, it is not an error + // since we can always fill in a pattern directly, albeit slower. + unsigned int *memblock = static_cast(block_buffer_); + block->SetPattern(patternlist_->GetRandomPattern()); + + logprintf(11, "Log: Warning, using pattern fill fallback in " + "DiskThread::WriteBlockToDisk on disk %s (thread %d).\n", + device_name_.c_str(), thread_num_); + + for (int i = 0; i < block->GetSize()/wordsize_; i++) { + memblock[i] = block->GetPattern()->pattern(i); + } + } else { + memcpy(block_buffer_, pe.addr, block->GetSize()); + block->SetPattern(pe.pattern); + sat_->PutValid(&pe); + } + + logprintf(12, "Log: Writing %lld sectors starting at %lld on disk %s" + " (thread %d).\n", + block->GetSize()/kSectorSize, block->GetAddress(), + device_name_.c_str(), thread_num_); + + int64 start_time = GetTime(); + + if (!AsyncDiskIO(ASYNC_IO_WRITE, fd, block_buffer_, block->GetSize(), + block->GetAddress() * kSectorSize, write_timeout_)) { + return false; + } + + int64 end_time = GetTime(); + logprintf(12, "Log: Writing time: %lld us (thread %d).\n", + end_time - start_time, thread_num_); + if (end_time - start_time > write_threshold_) { + logprintf(5, "Log: Write took %lld us which is longer than threshold " + "%lld us on disk %s (thread %d).\n", + end_time - start_time, write_threshold_, device_name_.c_str(), + thread_num_); + } + + return true; +} + +// Verify a block on disk. +bool DiskThread::ValidateBlockOnDisk(int fd, BlockData *block) { + int64 blocks = block->GetSize() / read_block_size_; + int64 bytes_read = 0; + int64 current_blocks; + int64 current_bytes; + uint64 address = block->GetAddress(); + + logprintf(20, "Log: Reading sectors starting at %lld on disk %s " + "(thread %d).\n", + address, device_name_.c_str(), thread_num_); + + // Read block from disk and time the read. If it takes longer than the + // threshold, complain. + if (lseek(fd, address * kSectorSize, SEEK_SET) == -1) { + logprintf(0, "Process Error: Unable to seek to sector %lld in " + "DiskThread::ValidateSectorsOnDisk on disk %s " + "(thread %d).\n", address, device_name_.c_str(), thread_num_); + return false; + } + int64 start_time = GetTime(); + + // Split a large write-sized block into small read-sized blocks and + // read them in groups of randomly-sized multiples of read block size. + // This assures all data written on disk by this particular block + // will be tested using a random reading pattern. + + while (blocks != 0) { + // Test all read blocks in a written block. + current_blocks = (random() % blocks) + 1; + current_bytes = current_blocks * read_block_size_; + + memset(block_buffer_, 0, current_bytes); + + logprintf(20, "Log: Reading %lld sectors starting at sector %lld on " + "disk %s (thread %d)\n", + current_bytes / kSectorSize, + (address * kSectorSize + bytes_read) / kSectorSize, + device_name_.c_str(), thread_num_); + + if (!AsyncDiskIO(ASYNC_IO_READ, fd, block_buffer_, current_bytes, + address * kSectorSize + bytes_read, + write_timeout_)) { + return false; + } + + int64 end_time = GetTime(); + logprintf(20, "Log: Reading time: %lld us (thread %d).\n", + end_time - start_time, thread_num_); + if (end_time - start_time > read_threshold_) { + logprintf(5, "Log: Read took %lld us which is longer than threshold " + "%lld us on disk %s (thread %d).\n", + end_time - start_time, read_threshold_, + device_name_.c_str(), thread_num_); + } + + // In non-destructive mode, don't compare the block to the pattern since + // the block was never written to disk in the first place. + if (!non_destructive_) { + if (CheckRegion(block_buffer_, block->GetPattern(), current_bytes, + 0, bytes_read)) { + os_->ErrorReport(device_name_.c_str(), "disk-pattern-error", 1); + errorcount_ += 1; + logprintf(0, "Hardware Error: Pattern mismatch in block starting at " + "sector %lld in DiskThread::ValidateSectorsOnDisk on " + "disk %s (thread %d).\n", + address, device_name_.c_str(), thread_num_); + } + } + + bytes_read += current_blocks * read_block_size_; + blocks -= current_blocks; + } + + return true; +} + +int DiskThread::Work() { + int fd; + + logprintf(9, "Log: Starting disk thread %d, disk %s\n", + thread_num_, device_name_.c_str()); + + srandom(time(NULL)); + + if (!OpenDevice(&fd)) { + return 0; + } + + // Allocate a block buffer aligned to 512 bytes since the kernel requires it + // when using direst IO. + block_buffer_ = memalign(kBufferAlignment, write_block_size_); + if (block_buffer_ == NULL) { + CloseDevice(fd); + logprintf(0, "Process Error: Unable to allocate memory for buffers " + "for disk %s (thread %d).\n", + device_name_.c_str(), thread_num_); + return 0; + } + + if (io_setup(5, &aio_ctx_)) { + logprintf(0, "Process Error: Unable to create aio context for disk %s" + " (thread %d).\n", + device_name_.c_str(), thread_num_); + return 0; + } + + DoWork(fd); + + status_ = 1; + + io_destroy(aio_ctx_); + CloseDevice(fd); + free(block_buffer_); + + logprintf(9, "Log: Completed %d (disk %s): disk thread status %d, " + "%d pages copied\n", + thread_num_, device_name_.c_str(), status_, pages_copied_); + return 1; +} + +RandomDiskThread::RandomDiskThread(DiskBlockTable *block_table) + : DiskThread(block_table) { + update_block_table_ = 0; +} + +RandomDiskThread::~RandomDiskThread() { +} + +bool RandomDiskThread::DoWork(int fd) { + blocks_read_ = 0; + blocks_written_ = 0; + logprintf(11, "Random phase for disk %s (thread %d).\n", + device_name_.c_str(), thread_num_); + while (IsReadyToRun()) { + BlockData *block = block_table_->GetRandomBlock(); + if (block == NULL) { + logprintf(12, "No block available for device %s (thread %d).\n", + device_name_.c_str(), thread_num_); + } else { + ValidateBlockOnDisk(fd, block); + block_table_->ReleaseBlock(block); + blocks_read_++; + } + } + pages_copied_ = blocks_read_; + return true; +} + +MemoryRegionThread::MemoryRegionThread() { + error_injection_ = false; + pages_ = NULL; +} + +MemoryRegionThread::~MemoryRegionThread() { + if (pages_ != NULL) + delete pages_; +} + +bool MemoryRegionThread::SetRegion(void *region, int64 size) { + int plength = sat_->page_length(); + int npages = size / plength; + if (size % plength) { + logprintf(0, "Process Error: region size is not a multiple of SAT " + "page length\n"); + return false; + } else { + if (pages_ != NULL) + delete pages_; + pages_ = new PageEntryQueue(npages); + char *base_addr = reinterpret_cast(region); + region_ = base_addr; + for (int i = 0; i < npages; i++) { + struct page_entry pe; + init_pe(&pe); + pe.addr = reinterpret_cast(base_addr + i * plength); + pe.offset = i * plength; + + pages_->Push(&pe); + } + return true; + } +} + +void MemoryRegionThread::ProcessError(struct ErrorRecord *error, + int priority, + const char *message) { + uint32 buffer_offset; + if (phase_ == kPhaseCopy) { + // If the error occurred on the Copy Phase, it means that + // the source data (i.e., the main memory) is wrong. so + // just pass it to the original ProcessError to call a + // bad-dimm error + WorkerThread::ProcessError(error, priority, message); + } else if (phase_ == kPhaseCheck) { + // A error on the Check Phase means that the memory region tested + // has an error. Gathering more information and then reporting + // the error. + // Determine if this is a write or read error. + os_->Flush(error->vaddr); + error->reread = *(error->vaddr); + char *good = reinterpret_cast(&(error->expected)); + char *bad = reinterpret_cast(&(error->actual)); + sat_assert(error->expected != error->actual); + unsigned int offset = 0; + for (offset = 0; offset < (sizeof(error->expected) - 1); offset++) { + if (good[offset] != bad[offset]) + break; + } + + error->vbyteaddr = reinterpret_cast(error->vaddr) + offset; + + buffer_offset = error->vbyteaddr - region_; + + // Find physical address if possible. + error->paddr = os_->VirtualToPhysical(error->vbyteaddr); + logprintf(priority, + "%s: miscompare on %s, CRC check at %p(0x%llx), " + "offset %llx: read:0x%016llx, reread:0x%016llx " + "expected:0x%016llx\n", + message, + identifier_.c_str(), + error->vaddr, + error->paddr, + buffer_offset, + error->actual, + error->reread, + error->expected); + } else { + logprintf(0, "Process Error: memory region thread raised an " + "unexpected error."); + } +} + +int MemoryRegionThread::Work() { + struct page_entry source_pe; + struct page_entry memregion_pe; + int result = 1; + int64 loops = 0; + const uint64 error_constant = 0x00ba00000000ba00LL; + + // For error injection. + int64 *addr = 0x0; + int offset = 0; + int64 data = 0; + + logprintf(9, "Log: Starting Memory Region thread %d\n", thread_num_); + + while (IsReadyToRun()) { + // Getting pages from SAT and queue. + phase_ = kPhaseNoPhase; + result &= sat_->GetValid(&source_pe); + if (!result) { + logprintf(0, "Process Error: memory region thread failed to pop " + "pages from SAT, bailing\n"); + break; + } + + result &= pages_->PopRandom(&memregion_pe); + if (!result) { + logprintf(0, "Process Error: memory region thread failed to pop " + "pages from queue, bailing\n"); + break; + } + + // Error injection for CRC copy. + if ((sat_->error_injection() || error_injection_) && loops == 1) { + addr = reinterpret_cast(source_pe.addr); + offset = random() % (sat_->page_length() / wordsize_); + data = addr[offset]; + addr[offset] = error_constant; + } + + // Copying SAT page into memory region. + phase_ = kPhaseCopy; + CrcCopyPage(&memregion_pe, &source_pe); + memregion_pe.pattern = source_pe.pattern; + + // Error injection for CRC Check. + if ((sat_->error_injection() || error_injection_) && loops == 2) { + addr = reinterpret_cast(memregion_pe.addr); + offset = random() % (sat_->page_length() / wordsize_); + data = addr[offset]; + addr[offset] = error_constant; + } + + // Checking page content in memory region. + phase_ = kPhaseCheck; + CrcCheckPage(&memregion_pe); + + phase_ = kPhaseNoPhase; + // Storing pages on their proper queues. + result &= sat_->PutValid(&source_pe); + if (!result) { + logprintf(0, "Process Error: memory region thread failed to push " + "pages into SAT, bailing\n"); + break; + } + result &= pages_->Push(&memregion_pe); + if (!result) { + logprintf(0, "Process Error: memory region thread failed to push " + "pages into queue, bailing\n"); + break; + } + + if ((sat_->error_injection() || error_injection_) && + loops >= 1 && loops <= 2) { + addr[offset] = data; + } + + loops++; + YieldSelf(); + } + + pages_copied_ = loops; + status_ = result; + logprintf(9, "Log: Completed %d: Memory Region thread. Status %d, %d " + "pages checked\n", thread_num_, status_, pages_copied_); + return 1; +} diff --git a/src/worker.h b/src/worker.h new file mode 100644 index 0000000..b85f926 --- /dev/null +++ b/src/worker.h @@ -0,0 +1,782 @@ +// Copyright 2006 Google Inc. All Rights Reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// worker.h : worker thread interface + +// This file contains the Worker Thread class interface +// for the SAT test. Worker Threads implement a repetative +// task used to test or stress the system. + +#ifndef STRESSAPPTEST_WORKER_H_ +#define STRESSAPPTEST_WORKER_H_ + +#include + +#include +#include + +#include + +#include +#include +#include +#include + +// This file must work with autoconf on its public version, +// so these includes are correct. +#include "disk_blocks.h" +#include "queue.h" +#include "sattypes.h" + + +// Global Datastruture shared by the Cache Coherency Worker Threads. +struct cc_cacheline_data { + int *num; +}; + +// Typical usage: +// (Other workflows may be possible, see function comments for details.) +// - Control thread creates object. +// - Control thread calls AddWorkers(1) for each worker thread. +// - Control thread calls Initialize(). +// - Control thread launches worker threads. +// - Every worker thread frequently calls ContinueRunning(). +// - Control thread periodically calls PauseWorkers(), effectively sleeps, and +// then calls ResumeWorkers(). +// - Some worker threads may exit early, before StopWorkers() is called. They +// call RemoveSelf() after their last call to ContinueRunning(). +// - Control thread eventually calls StopWorkers(). +// - Worker threads exit. +// - Control thread joins worker threads. +// - Control thread calls Destroy(). +// - Control thread destroys object. +// +// Threadsafety: +// - ContinueRunning() may be called concurrently by different workers, but not +// by a single worker. +// - No other methods may ever be called concurrently, with themselves or +// eachother. +// - This object may be used by multiple threads only between Initialize() and +// Destroy(). +// +// TODO(matthewb): Move this class and its unittest to their own files. +class WorkerStatus { + public: + //-------------------------------- + // Methods for the control thread. + //-------------------------------- + + WorkerStatus() : num_workers_(0), status_(RUN) {} + + // Called by the control thread to increase the worker count. Must be called + // before Initialize(). The worker count is 0 upon object initialization. + void AddWorkers(int num_new_workers) { + // No need to lock num_workers_mutex_ because this is before Initialize(). + num_workers_ += num_new_workers; + } + + // Called by the control thread. May not be called multiple times. If + // called, Destroy() must be called before destruction. + void Initialize(); + + // Called by the control thread after joining all worker threads. Must be + // called iff Initialize() was called. No methods may be called after calling + // this. + void Destroy(); + + // Called by the control thread to tell the workers to pause. Does not return + // until all workers have called ContinueRunning() or RemoveSelf(). May only + // be called between Initialize() and Stop(). Must not be called multiple + // times without ResumeWorkers() having been called inbetween. + void PauseWorkers(); + + // Called by the control thread to tell the workers to resume from a pause. + // May only be called between Initialize() and Stop(). May only be called + // directly after PauseWorkers(). + void ResumeWorkers(); + + // Called by the control thread to tell the workers to stop. May only be + // called between Initialize() and Destroy(). May only be called once. + void StopWorkers(); + + //-------------------------------- + // Methods for the worker threads. + //-------------------------------- + + // Called by worker threads to decrease the worker count by one. May only be + // called between Initialize() and Destroy(). May wait for ResumeWorkers() + // when called after PauseWorkers(). + void RemoveSelf(); + + // Called by worker threads between Initialize() and Destroy(). May be called + // any number of times. Return value is whether or not the worker should + // continue running. When called after PauseWorkers(), does not return until + // ResumeWorkers() or StopWorkers() has been called. Number of distinct + // calling threads must match the worker count (see AddWorkers() and + // RemoveSelf()). + bool ContinueRunning(); + + // TODO(matthewb): Is this functionality really necessary? Remove it if not. + // + // This is a hack! It's like ContinueRunning(), except it won't pause. If + // any worker threads use this exclusively in place of ContinueRunning() then + // PauseWorkers() should never be used! + bool ContinueRunningNoPause(); + + private: + enum Status { RUN, PAUSE, STOP }; + + void WaitOnPauseBarrier() { + int error = pthread_barrier_wait(&pause_barrier_); + if (error != PTHREAD_BARRIER_SERIAL_THREAD) + sat_assert(error == 0); + } + + void AcquireNumWorkersLock() { + sat_assert(0 == pthread_mutex_lock(&num_workers_mutex_)); + } + + void ReleaseNumWorkersLock() { + sat_assert(0 == pthread_mutex_unlock(&num_workers_mutex_)); + } + + void AcquireStatusReadLock() { + sat_assert(0 == pthread_rwlock_rdlock(&status_rwlock_)); + } + + void AcquireStatusWriteLock() { + sat_assert(0 == pthread_rwlock_wrlock(&status_rwlock_)); + } + + void ReleaseStatusLock() { + sat_assert(0 == pthread_rwlock_unlock(&status_rwlock_)); + } + + Status GetStatus() { + AcquireStatusReadLock(); + Status status = status_; + ReleaseStatusLock(); + return status; + } + + // Returns the previous status. + Status SetStatus(Status status) { + AcquireStatusWriteLock(); + Status prev_status = status_; + status_ = status; + ReleaseStatusLock(); + return prev_status; + } + + pthread_mutex_t num_workers_mutex_; + int num_workers_; + + pthread_rwlock_t status_rwlock_; + Status status_; + + // Guaranteed to not be in use when (status_ != PAUSE). + pthread_barrier_t pause_barrier_; + + DISALLOW_COPY_AND_ASSIGN(WorkerStatus); +}; + + +// This is a base class for worker threads. +// Each thread repeats a specific +// task on various blocks of memory. +class WorkerThread { + public: + // Enum to mark a thread as low/med/high priority. + enum Priority { + Low, + Normal, + High, + }; + WorkerThread(); + virtual ~WorkerThread(); + + // Initialize values and thread ID number. + void InitThread(int thread_num_init, + class Sat *sat_init, + class OsLayer *os_init, + class PatternList *patternlist_init, + WorkerStatus *worker_status); + + // This function is DEPRECATED, it does nothing. + void SetPriority(Priority priority) { priority_ = priority; } + // Spawn the worker thread, by running Work(). + int SpawnThread(); + // Only for ThreadSpawnerGeneric(). + void StartRoutine(); + bool InitPriority(); + + // Wait for the thread to complete its cleanup. + virtual int JoinThread(); + // Kill worker thread with SIGINT. + virtual int KillThread(); + + // This is the task function that the thread executes. + // This is implemented per subclass. + virtual int Work(); + + // Starts per-WorkerThread timer. + void StartThreadTimer() {gettimeofday(&start_time_, NULL);} + // Reads current timer value and returns run duration without recording it. + int64 ReadThreadTimer() { + struct timeval end_time_; + gettimeofday(&end_time_, NULL); + return (end_time_.tv_sec - start_time_.tv_sec)*1000000 + + (end_time_.tv_usec - start_time_.tv_usec); + } + // Stops per-WorkerThread timer and records thread run duration. + // Start/Stop ThreadTimer repetitively has cumulative effect, ie the timer + // is effectively paused and restarted, so runduration_usec accumulates on. + void StopThreadTimer() { + runduration_usec_ += ReadThreadTimer(); + } + + // Acccess member variables. + int GetStatus() {return status_;} + int64 GetErrorCount() {return errorcount_;} + int64 GetPageCount() {return pages_copied_;} + int64 GetRunDurationUSec() {return runduration_usec_;} + + // Returns bandwidth defined as pages_copied / thread_run_durations. + float GetCopiedData(); + // Calculate worker thread specific copied data. + virtual float GetMemoryCopiedData() {return 0;} + virtual float GetDeviceCopiedData() {return 0;} + // Calculate worker thread specific bandwidth. + virtual float GetMemoryBandwidth() + {return GetMemoryCopiedData() / ( + runduration_usec_ * 1.0 / 1000000);} + virtual float GetDeviceBandwidth() + {return GetDeviceCopiedData() / ( + runduration_usec_ * 1.0 / 1000000);} + + void set_cpu_mask(int32 mask) {cpu_mask_ = mask;} + void set_tag(int32 tag) {tag_ = tag;} + + // Returns CPU mask, where each bit represents a logical cpu. + uint32 AvailableCpus(); + // Returns CPU mask of CPUs this thread is bound to, + uint32 CurrentCpus(); + + int ThreadID() {return thread_num_;} + + // Bind worker thread to specified CPU(s) + bool BindToCpus(uint32 thread_mask); + + protected: + // This function dictates whether the main work loop + // continues, waits, or terminates. + // All work loops should be of the form: + // do { + // // work. + // } while (IsReadyToRun()); + virtual bool IsReadyToRun() { return worker_status_->ContinueRunning(); } + // TODO(matthewb): Is this function really necessary? Remove it if not. + // + // Like IsReadyToRun(), except it won't pause. + virtual bool IsReadyToRunNoPause() { + return worker_status_->ContinueRunningNoPause(); + } + + // These are functions used by the various work loops. + // Pretty print and log a data miscompare. + virtual void ProcessError(struct ErrorRecord *er, + int priority, + const char *message); + + // Compare a region of memory with a known data patter, and report errors. + virtual int CheckRegion(void *addr, + class Pattern *pat, + int64 length, + int offset, + int64 patternoffset); + + // Fast compare a block of memory. + virtual int CrcCheckPage(struct page_entry *srcpe); + + // Fast copy a block of memory, while verifying correctness. + virtual int CrcCopyPage(struct page_entry *dstpe, + struct page_entry *srcpe); + + // Fast copy a block of memory, while verifying correctness, and heating CPU. + virtual int CrcWarmCopyPage(struct page_entry *dstpe, + struct page_entry *srcpe); + + // Fill a page with its specified pattern. + virtual bool FillPage(struct page_entry *pe); + + // Copy with address tagging. + virtual bool AdlerAddrMemcpyC(uint64 *dstmem64, + uint64 *srcmem64, + unsigned int size_in_bytes, + AdlerChecksum *checksum, + struct page_entry *pe); + // Crc data with address tagging. + virtual bool AdlerAddrCrcC(uint64 *srcmem64, + unsigned int size_in_bytes, + AdlerChecksum *checksum, + struct page_entry *pe); + // Report a mistagged cacheline. + bool ReportTagError(uint64 *mem64, + uint64 actual, + uint64 tag); + // Print out the error record of the tag mismatch. + void ProcessTagError(struct ErrorRecord *error, + int priority, + const char *message); + + // A worker thread can yield itself to give up CPU until it's scheduled again + bool YieldSelf(); + + protected: + // General state variables that all subclasses need. + int thread_num_; // Thread ID. + volatile int status_; // Error status. + volatile int64 pages_copied_; // Recorded for memory bandwidth calc. + volatile int64 errorcount_; // Miscompares seen by this thread. + + volatile uint32 cpu_mask_; // Cores this thread is allowed to run on. + volatile uint32 tag_; // Tag hint for memory this thread can use. + + bool tag_mode_; // Tag cachelines with vaddr. + + // Thread timing variables. + struct timeval start_time_; // Worker thread start time. + volatile int64 runduration_usec_; // Worker run duration in u-seconds. + + // Function passed to pthread_create. + void *(*thread_spawner_)(void *args); + pthread_t thread_; // Pthread thread ID. + Priority priority_; // Worker thread priority. + class Sat *sat_; // Reference to parent stest object. + class OsLayer *os_; // Os abstraction: put hacks here. + class PatternList *patternlist_; // Reference to data patterns. + + // Work around style guide ban on sizeof(int). + static const uint64 iamint_ = 0; + static const int wordsize_ = sizeof(iamint_); + + private: + WorkerStatus *worker_status_; + + DISALLOW_COPY_AND_ASSIGN(WorkerThread); +}; + +// Worker thread to perform File IO. +class FileThread : public WorkerThread { + public: + FileThread(); + // Set filename to use for file IO. + virtual void SetFile(const char *filename_init); + virtual int Work(); + + // Calculate worker thread specific bandwidth. + virtual float GetDeviceCopiedData() + {return GetCopiedData()*2;} + virtual float GetMemoryCopiedData(); + + protected: + // Record of where these pages were sourced from, and what + // potentially broken components they passed through. + struct PageRec { + struct Pattern *pattern; // This is the data it should contain. + void *src; // This is the memory location the data was sourced from. + void *dst; // This is where it ended up. + }; + + // These are functions used by the various work loops. + // Pretty print and log a data miscompare. Disks require + // slightly different error handling. + virtual void ProcessError(struct ErrorRecord *er, + int priority, + const char *message); + + virtual bool OpenFile(int *pfile); + virtual bool CloseFile(int fd); + + // Read and write whole file to disk. + virtual bool WritePages(int fd); + virtual bool ReadPages(int fd); + + // Read and write pages to disk. + virtual bool WritePageToFile(int fd, struct page_entry *src); + virtual bool ReadPageFromFile(int fd, struct page_entry *dst); + + // Sector tagging support. + virtual bool SectorTagPage(struct page_entry *src, int block); + virtual bool SectorValidatePage(const struct PageRec &page, + struct page_entry *dst, + int block); + + // Get memory for an incoming data transfer.. + virtual bool PagePrepare(); + // Remove memory allocated for data transfer. + virtual bool PageTeardown(); + + // Get memory for an incoming data transfer.. + virtual bool GetEmptyPage(struct page_entry *dst); + // Get memory for an outgoing data transfer.. + virtual bool GetValidPage(struct page_entry *dst); + // Throw out a used empty page. + virtual bool PutEmptyPage(struct page_entry *src); + // Throw out a used, filled page. + virtual bool PutValidPage(struct page_entry *src); + + + struct PageRec *page_recs_; // Array of page records. + int crc_page_; // Page currently being CRC checked. + string filename_; // Name of file to access. + string devicename_; // Name of device file is on. + + bool page_io_; // Use page pool for IO. + void *local_page_; // malloc'd page fon non-pool IO. + int pass_; // Number of writes to the file so far. + + // Tag to detect file corruption. + struct SectorTag { + volatile uint8 magic; + volatile uint8 block; + volatile uint8 sector; + volatile uint8 pass; + char pad[512-4]; + }; + + DISALLOW_COPY_AND_ASSIGN(FileThread); +}; + + +// Worker thread to perform Network IO. +class NetworkThread : public WorkerThread { + public: + NetworkThread(); + // Set hostname to use for net IO. + virtual void SetIP(const char *ipaddr_init); + virtual int Work(); + + // Calculate worker thread specific bandwidth. + virtual float GetDeviceCopiedData() + {return GetCopiedData()*2;} + + protected: + // IsReadyToRunNoPause() wrapper, for NetworkSlaveThread to override. + virtual bool IsNetworkStopSet(); + virtual bool CreateSocket(int *psocket); + virtual bool CloseSocket(int sock); + virtual bool Connect(int sock); + virtual bool SendPage(int sock, struct page_entry *src); + virtual bool ReceivePage(int sock, struct page_entry *dst); + char ipaddr_[256]; + int sock_; + + private: + DISALLOW_COPY_AND_ASSIGN(NetworkThread); +}; + +// Worker thread to reflect Network IO. +class NetworkSlaveThread : public NetworkThread { + public: + NetworkSlaveThread(); + // Set socket for IO. + virtual void SetSock(int sock); + virtual int Work(); + + protected: + virtual bool IsNetworkStopSet(); + + private: + DISALLOW_COPY_AND_ASSIGN(NetworkSlaveThread); +}; + +// Worker thread to detect incoming Network IO. +class NetworkListenThread : public NetworkThread { + public: + NetworkListenThread(); + virtual int Work(); + + private: + virtual bool Listen(); + virtual bool Wait(); + virtual bool GetConnection(int *pnewsock); + virtual bool SpawnSlave(int newsock, int threadid); + virtual bool ReapSlaves(); + + // For serviced incoming connections. + struct ChildWorker { + WorkerStatus status; + NetworkSlaveThread thread; + }; + typedef vector ChildVector; + ChildVector child_workers_; + + DISALLOW_COPY_AND_ASSIGN(NetworkListenThread); +}; + +// Worker thread to perform Memory Copy. +class CopyThread : public WorkerThread { + public: + CopyThread() {} + virtual int Work(); + // Calculate worker thread specific bandwidth. + virtual float GetMemoryCopiedData() + {return GetCopiedData()*2;} + + private: + DISALLOW_COPY_AND_ASSIGN(CopyThread); +}; + +// Worker thread to perform Memory Invert. +class InvertThread : public WorkerThread { + public: + InvertThread() {} + virtual int Work(); + // Calculate worker thread specific bandwidth. + virtual float GetMemoryCopiedData() + {return GetCopiedData()*4;} + + private: + virtual int InvertPageUp(struct page_entry *srcpe); + virtual int InvertPageDown(struct page_entry *srcpe); + DISALLOW_COPY_AND_ASSIGN(InvertThread); +}; + +// Worker thread to fill blank pages on startup. +class FillThread : public WorkerThread { + public: + FillThread(); + // Set how many pages this thread should fill before exiting. + virtual void SetFillPages(int64 num_pages_to_fill_init); + virtual int Work(); + + private: + // Fill a page with the data pattern in pe->pattern. + virtual bool FillPageRandom(struct page_entry *pe); + int64 num_pages_to_fill_; + DISALLOW_COPY_AND_ASSIGN(FillThread); +}; + +// Worker thread to verify page data matches pattern data. +// Thread will check and replace pages until "done" flag is set, +// then it will check and discard pages until no more remain. +class CheckThread : public WorkerThread { + public: + CheckThread() {} + virtual int Work(); + // Calculate worker thread specific bandwidth. + virtual float GetMemoryCopiedData() + {return GetCopiedData();} + + private: + DISALLOW_COPY_AND_ASSIGN(CheckThread); +}; + + +// Worker thread to poll for system error messages. +// Thread will check for messages until "done" flag is set. +class ErrorPollThread : public WorkerThread { + public: + ErrorPollThread() {} + virtual int Work(); + + private: + DISALLOW_COPY_AND_ASSIGN(ErrorPollThread); +}; + +// Computation intensive worker thread to stress CPU. +class CpuStressThread : public WorkerThread { + public: + CpuStressThread() {} + virtual int Work(); + + private: + DISALLOW_COPY_AND_ASSIGN(CpuStressThread); +}; + +// Worker thread that tests the correctness of the +// CPU Cache Coherency Protocol. +class CpuCacheCoherencyThread : public WorkerThread { + public: + CpuCacheCoherencyThread(cc_cacheline_data *cc_data, + int cc_cacheline_count_, + int cc_thread_num_, + int cc_inc_count_); + virtual int Work(); + + protected: + cc_cacheline_data *cc_cacheline_data_; // Datstructure for each cacheline. + int cc_local_num_; // Local counter for each thread. + int cc_cacheline_count_; // Number of cache lines to operate on. + int cc_thread_num_; // The integer id of the thread which is + // used as an index into the integer array + // of the cacheline datastructure. + int cc_inc_count_; // Number of times to increment the counter. + + private: + DISALLOW_COPY_AND_ASSIGN(CpuCacheCoherencyThread); +}; + +// Worker thread to perform disk test. +class DiskThread : public WorkerThread { + public: + explicit DiskThread(DiskBlockTable *block_table); + virtual ~DiskThread(); + // Calculate disk thread specific bandwidth. + virtual float GetDeviceCopiedData() { + return (blocks_written_ * write_block_size_ + + blocks_read_ * read_block_size_) / kMegabyte;} + + // Set filename for device file (in /dev). + virtual void SetDevice(const char *device_name); + // Set various parameters that control the behaviour of the test. + virtual bool SetParameters(int read_block_size, + int write_block_size, + int64 segment_size, + int64 cache_size, + int blocks_per_segment, + int64 read_threshold, + int64 write_threshold, + int non_destructive); + + virtual int Work(); + + virtual float GetMemoryCopiedData() {return 0;} + + protected: + static const int kSectorSize = 512; // Size of sector on disk. + static const int kBufferAlignment = 512; // Buffer alignment required by the + // kernel. + static const int kBlockRetry = 100; // Number of retries to allocate + // sectors. + + enum IoOp { + ASYNC_IO_READ = 0, + ASYNC_IO_WRITE = 1 + }; + + virtual bool OpenDevice(int *pfile); + virtual bool CloseDevice(int fd); + + // Retrieves the size (in bytes) of the disk/file. + virtual bool GetDiskSize(int fd); + + // Retrieves the current time in microseconds. + virtual int64 GetTime(); + + // Do an asynchronous disk I/O operation. + virtual bool AsyncDiskIO(IoOp op, int fd, void *buf, int64 size, + int64 offset, int64 timeout); + + // Write a block to disk. + virtual bool WriteBlockToDisk(int fd, BlockData *block); + + // Verify a block on disk. + virtual bool ValidateBlockOnDisk(int fd, BlockData *block); + + // Main work loop. + virtual bool DoWork(int fd); + + int read_block_size_; // Size of blocks read from disk, in bytes. + int write_block_size_; // Size of blocks written to disk, in bytes. + int64 blocks_read_; // Number of blocks read in work loop. + int64 blocks_written_; // Number of blocks written in work loop. + int64 segment_size_; // Size of disk segments (in bytes) that the disk + // will be split into where testing can be + // confined to a particular segment. + // Allows for control of how evenly the disk will + // be tested. Smaller segments imply more even + // testing (less random). + int blocks_per_segment_; // Number of blocks that will be tested per + // segment. + int cache_size_; // Size of disk cache, in bytes. + int queue_size_; // Length of in-flight-blocks queue, in blocks. + int non_destructive_; // Use non-destructive mode or not. + int update_block_table_; // If true, assume this is the thread + // responsible for writing the data in the disk + // for this block device and, therefore, + // update the block table. If false, just use + // the block table to get data. + + // read/write times threshold for reporting a problem + int64 read_threshold_; // Maximum time a read should take (in us) before + // a warning is given. + int64 write_threshold_; // Maximum time a write should take (in us) before + // a warning is given. + int64 read_timeout_; // Maximum time a read can take before a timeout + // and the aborting of the read operation. + int64 write_timeout_; // Maximum time a write can take before a timeout + // and the aborting of the write operation. + + string device_name_; // Name of device file to access. + int64 device_sectors_; // Number of sectors on the device. + + std::queue in_flight_sectors_; // Queue of sectors written but + // not verified. + void *block_buffer_; // Pointer to aligned block buffer. + + aio_context_t aio_ctx_; // Asynchronous I/O context for Linux native AIO. + + DiskBlockTable *block_table_; // Disk Block Table, shared by all disk + // threads that read / write at the same + // device + + DISALLOW_COPY_AND_ASSIGN(DiskThread); +}; + +class RandomDiskThread : public DiskThread { + public: + explicit RandomDiskThread(DiskBlockTable *block_table); + virtual ~RandomDiskThread(); + // Main work loop. + virtual bool DoWork(int fd); + protected: + DISALLOW_COPY_AND_ASSIGN(RandomDiskThread); +}; + +// Worker thread to perform checks in a specific memory region. +class MemoryRegionThread : public WorkerThread { + public: + MemoryRegionThread(); + ~MemoryRegionThread(); + virtual int Work(); + void ProcessError(struct ErrorRecord *error, int priority, + const char *message); + bool SetRegion(void *region, int64 size); + // Calculate worker thread specific bandwidth. + virtual float GetMemoryCopiedData() + {return GetCopiedData();} + virtual float GetDeviceCopiedData() + {return GetCopiedData() * 2;} + void SetIdentifier(string identifier) { + identifier_ = identifier; + } + + protected: + // Page queue for this particular memory region. + char *region_; + PageEntryQueue *pages_; + bool error_injection_; + int phase_; + string identifier_; + static const int kPhaseNoPhase = 0; + static const int kPhaseCopy = 1; + static const int kPhaseCheck = 2; + + private: + DISALLOW_COPY_AND_ASSIGN(MemoryRegionThread); +}; + +#endif // STRESSAPPTEST_WORKER_H_ -- 2.30.2