aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Anderson <saa@android.com>2012-02-17 14:25:17 -0800
committerScott Anderson <saa@android.com>2012-04-10 11:13:48 -0700
commit8f1c60d605d31447b4f9ccf86029790bed3fb3f3 (patch)
tree8f7a30b762f94b30a4f615d43a9ce07b5acc0370
parentb0114cb9f332db144f65291211ae65f7f0e814e6 (diff)
downloadstressapptest-8f1c60d605d31447b4f9ccf86029790bed3fb3f3.tar.gz
Improve portability.
At a high level, #ifdefs were added to the code to allow it to be used on systems that were missing various libraries, function and defines. configure.ac was enhanced to test for more of these things and set defines to indicate their presence or absence. In addition, it was slightly tweaked to match the output of autoscan. autoheader and autoconf were ran to update the configure files. The goal was that the resultant code should not be modified if the libraries/functions/defines were all present. The code for the cases where something is missing is workable, but can probably be improved. ifdefs newly added to the code include: HAVE_LIBAIO_H HAVE_MMAP64 HAVE_POSIX_MEMALIGN HAVE_RAND_R HAVE_SCHED_GETAFFINITY HAVE_SYS_SHM_H O_DSYNC _POSIX_BARRIERS STRERROR_R_CHAR_P Signed-off-by: Scott Anderson <saa@android.com>
-rwxr-xr-xconfigure324
-rw-r--r--configure.ac73
-rw-r--r--src/os.cc18
-rw-r--r--src/sat.cc15
-rw-r--r--src/sattypes.h7
-rw-r--r--src/stressapptest_config.h.in24
-rw-r--r--src/worker.cc56
-rw-r--r--src/worker.h8
8 files changed, 325 insertions, 200 deletions
diff --git a/configure b/configure
index 42df1a2..3f27d49 100755
--- a/configure
+++ b/configure
@@ -4958,6 +4958,7 @@ $as_echo "#define STDC_HEADERS 1" >>confdefs.h
fi
+# Skip malloc.h to prevent redefinition of HAVE_MALLOC_H on some platforms
# 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
@@ -4976,7 +4977,7 @@ 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
+for ac_header in arpa/inet.h fcntl.h netdb.h stdint.h stdlib.h string.h sys/ioctl.h sys/socket.h sys/time.h unistd.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@@ -5003,15 +5004,66 @@ if test "x$ac_cv_header_pthread_h" = x""yes; then :
#define HAVE_PTHREAD_H 1
_ACEOF
-else
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "Missing pthread.h.
-See \`config.log' for more details." "$LINENO" 5; }
fi
done
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_create" >&5
+$as_echo_n "checking for library containing pthread_create... " >&6; }
+if test "${ac_cv_search_pthread_create+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* 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 pthread_create ();
+int
+main ()
+{
+return pthread_create ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' pthread; 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
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_pthread_create=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_pthread_create+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_pthread_create+set}" = set; then :
+
+else
+ ac_cv_search_pthread_create=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_pthread_create" >&5
+$as_echo "$ac_cv_search_pthread_create" >&6; }
+ac_res=$ac_cv_search_pthread_create
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
for ac_header in libaio.h
do :
ac_fn_c_check_header_mongrel "$LINENO" "libaio.h" "ac_cv_header_libaio_h" "$ac_includes_default"
@@ -5020,15 +5072,66 @@ if test "x$ac_cv_header_libaio_h" = x""yes; then :
#define HAVE_LIBAIO_H 1
_ACEOF
-else
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "Missing libaio.h.
-See \`config.log' for more details." "$LINENO" 5; }
fi
done
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing io_setup" >&5
+$as_echo_n "checking for library containing io_setup... " >&6; }
+if test "${ac_cv_search_io_setup+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* 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 io_setup ();
+int
+main ()
+{
+return io_setup ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' aio; 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
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_io_setup=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_io_setup+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_io_setup+set}" = set; then :
+
+else
+ ac_cv_search_io_setup=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_io_setup" >&5
+$as_echo "$ac_cv_search_io_setup" >&6; }
+ac_res=$ac_cv_search_io_setup
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
for ac_header in sys/shm.h
do :
ac_fn_c_check_header_mongrel "$LINENO" "sys/shm.h" "ac_cv_header_sys_shm_h" "$ac_includes_default"
@@ -5037,15 +5140,66 @@ if test "x$ac_cv_header_sys_shm_h" = x""yes; then :
#define HAVE_SYS_SHM_H 1
_ACEOF
-else
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "Missing sys/shm.h from librt.
-See \`config.log' for more details." "$LINENO" 5; }
fi
done
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing shm_open" >&5
+$as_echo_n "checking for library containing shm_open... " >&6; }
+if test "${ac_cv_search_shm_open+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* 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 shm_open ();
+int
+main ()
+{
+return shm_open ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' rt; 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
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_shm_open=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_shm_open+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_shm_open+set}" = set; then :
+
+else
+ ac_cv_search_shm_open=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_shm_open" >&5
+$as_echo "$ac_cv_search_shm_open" >&6; }
+ac_res=$ac_cv_search_shm_open
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
# Checks for typedefs, structures, and compiler characteristics.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5
@@ -5337,6 +5491,17 @@ _ACEOF
;;
esac
+ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = x""yes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned int
+_ACEOF
+
+fi
+
ac_fn_c_check_type "$LINENO" "ssize_t" "ac_cv_type_ssize_t" "$ac_includes_default"
if test "x$ac_cv_type_ssize_t" = x""yes; then :
@@ -5431,118 +5596,6 @@ fi
-# These are the libraries stressapptest requires to build.
-# We'll check that they work, and fail otherwise.
-# In the future we may provide for testing alternate
-# arguments, but that's not necessary now.
-LIBS="$LIBS -lrt -pthread -laio"
-
-# Checking for pthreads
-pthread_arg="not_available"
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if pthreads is supported" >&5
-$as_echo_n "checking if pthreads is supported... " >&6; }
-
-pthread_header="#include<pthread.h>"
-pthread_body="pthread_create(0,0,0,0)"
-# Check if compile with no extra argument
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$pthread_header
-int
-main ()
-{
-$pthread_body
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- pthread_arg=""
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-
-if test x"$pthread_arg" = x"not_available"; then
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "Cannot find a proper pthread library
-See \`config.log' for more details." "$LINENO" 5; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-fi
-
-# Checking for libaio
-libaio_arg="not_available"
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if libaio is supported" >&5
-$as_echo_n "checking if libaio is supported... " >&6; }
-
-libaio_header="#include<libaio.h>"
-libaio_body="io_submit(0,0,0)"
-# Check if compile with no extra argument
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$libaio_header
-int
-main ()
-{
-$libaio_body
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- libaio_arg=""
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-
-if test x"$libaio_arg" = x"not_available"; then
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "Cannot find libaio library, please install libaio-dev
-See \`config.log' for more details." "$LINENO" 5; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-fi
-
-# Checking for librt
-librt_arg="not_available"
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if librt is supported" >&5
-$as_echo_n "checking if librt is supported... " >&6; }
-
-librt_header="#include<sys/shm.h>"
-librt_body="shm_open(0, 0, 0)"
-# Check if compile with no extra argument
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$librt_header
-int
-main ()
-{
-$librt_body
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- librt_arg=""
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-
-if test x"$librt_arg" = x"not_available"; then
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "Cannot find librt library
-See \`config.log' for more details." "$LINENO" 5; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-fi
-
-
# Checks for library functions.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether closedir returns void" >&5
$as_echo_n "checking whether closedir returns void... " >&6; }
@@ -5848,7 +5901,20 @@ fi
done
-for ac_func in gettimeofday memset select socket strtol strtoull
+for ac_func in ftruncate gettimeofday memset munmap select socket strtol strtoull
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in mmap64 posix_memalign rand_r sched_getaffinity
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
diff --git a/configure.ac b/configure.ac
index 5e82b9d..e1e44fa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,5 @@
AC_PREREQ(2.61)
-AC_INIT(stressapptest, 1.0.4_autoconf, opensource@google.com)
+AC_INIT([stressapptest], [1.0.4_autoconf], [opensource@google.com])
AC_ARG_WITH(static, [ --with-static enable static linking])
@@ -103,10 +103,14 @@ 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], [], [AC_MSG_FAILURE([Missing some header files.])])
-AC_CHECK_HEADERS([pthread.h], [], [AC_MSG_FAILURE([Missing pthread.h.])])
-AC_CHECK_HEADERS([libaio.h], [], [AC_MSG_FAILURE([Missing libaio.h.])])
-AC_CHECK_HEADERS([sys/shm.h], [], [AC_MSG_FAILURE([Missing sys/shm.h from librt.])])
+# Skip malloc.h to prevent redefinition of HAVE_MALLOC_H on some platforms
+AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h stdint.h stdlib.h string.h sys/ioctl.h sys/socket.h sys/time.h unistd.h], [], [AC_MSG_FAILURE([Missing some header files.])])
+AC_CHECK_HEADERS([pthread.h])
+AC_SEARCH_LIBS([pthread_create], [pthread])
+AC_CHECK_HEADERS([libaio.h])
+AC_SEARCH_LIBS([io_setup], [aio])
+AC_CHECK_HEADERS([sys/shm.h])
+AC_SEARCH_LIBS([shm_open], [rt])
# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STDBOOL
@@ -114,67 +118,13 @@ AC_C_CONST
AC_C_INLINE
AC_TYPE_PID_T
AC_C_RESTRICT
+AC_TYPE_SIZE_T
AC_TYPE_SSIZE_T
AC_HEADER_TIME
AC_TYPE_UINT16_T
AC_C_VOLATILE
-# These are the libraries stressapptest requires to build.
-# We'll check that they work, and fail otherwise.
-# In the future we may provide for testing alternate
-# arguments, but that's not necessary now.
-LIBS="$LIBS -lrt -pthread -laio"
-
-# Checking for pthreads
-pthread_arg="not_available"
-AC_MSG_CHECKING([if pthreads is supported])
-
-pthread_header="#include<pthread.h>"
-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
- AC_MSG_FAILURE([Cannot find a proper pthread library])
-else
- AC_MSG_RESULT([yes])
-fi
-
-# Checking for libaio
-libaio_arg="not_available"
-AC_MSG_CHECKING([if libaio is supported])
-
-libaio_header="#include<libaio.h>"
-libaio_body="io_submit(0,0,0)"
-# Check if compile with no extra argument
-AC_LINK_IFELSE([AC_LANG_PROGRAM($libaio_header, $libaio_body)],
-libaio_arg="")
-
-if test x"$libaio_arg" = x"not_available"; then
- AC_MSG_FAILURE([Cannot find libaio library, please install libaio-dev])
-else
- AC_MSG_RESULT([yes])
-fi
-
-# Checking for librt
-librt_arg="not_available"
-AC_MSG_CHECKING([if librt is supported])
-
-librt_header="#include<sys/shm.h>"
-librt_body="shm_open(0, 0, 0)"
-# Check if compile with no extra argument
-AC_LINK_IFELSE([AC_LANG_PROGRAM($librt_header, $librt_body)],
-librt_arg="")
-
-if test x"$librt_arg" = x"not_available"; then
- AC_MSG_FAILURE([Cannot find librt library])
-else
- AC_MSG_RESULT([yes])
-fi
-
-
# Checks for library functions.
AC_FUNC_CLOSEDIR_VOID
AC_PROG_GCC_TRADITIONAL
@@ -182,7 +132,8 @@ AC_FUNC_SELECT_ARGTYPES
AC_TYPE_SIGNAL
AC_FUNC_STRERROR_R
AC_FUNC_VPRINTF
-AC_CHECK_FUNCS([gettimeofday memset select socket strtol strtoull])
+AC_CHECK_FUNCS([ftruncate gettimeofday memset munmap select socket strtol strtoull])
+AC_CHECK_FUNCS([mmap64 posix_memalign rand_r sched_getaffinity])
AC_CONFIG_FILES([Makefile src/Makefile])
AC_OUTPUT
diff --git a/src/os.cc b/src/os.cc
index 1340d6b..3434baa 100644
--- a/src/os.cc
+++ b/src/os.cc
@@ -32,7 +32,9 @@
#include <sys/time.h>
#include <sys/types.h>
#include <sys/ipc.h>
+#ifdef HAVE_SYS_SHM_H
#include <sys/shm.h>
+#endif
#include <unistd.h>
#ifndef SHM_HUGETLB
@@ -396,6 +398,7 @@ bool OsLayer::AllocateTestMem(int64 length, uint64 paddr_base) {
logprintf(3, "Log: Prefer plain malloc memory allocation.\n");
}
+#ifdef HAVE_SYS_SHM_H
// Allocate hugepage mapped memory.
if (prefer_hugepages) {
do { // Allow break statement.
@@ -495,6 +498,7 @@ bool OsLayer::AllocateTestMem(int64 length, uint64 paddr_base) {
} while (0);
shm_unlink("/stressapptest");
}
+#endif // HAVE_SYS_SHM_H
if (!use_hugepages_ && !use_posix_shm_) {
// Use memalign to ensure that blocks are aligned enough for disk direct IO.
@@ -524,8 +528,10 @@ bool OsLayer::AllocateTestMem(int64 length, uint64 paddr_base) {
void OsLayer::FreeTestMem() {
if (testmem_) {
if (use_hugepages_) {
+#ifdef HAVE_SYS_SHM_H
shmdt(testmem_);
shmctl(shmid_, IPC_RMID, NULL);
+#endif
} else if (use_posix_shm_) {
if (!dynamic_mapped_shmem_) {
munmap(testmem_, testmemsize_);
@@ -546,9 +552,15 @@ void *OsLayer::PrepareTestMem(uint64 offset, uint64 length) {
if (dynamic_mapped_shmem_) {
// TODO(nsanders): Check if we can support MAP_NONBLOCK,
// and evaluate performance hit from not using it.
+#ifdef HAVE_MMAP64
void * mapping = mmap64(NULL, length, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_NORESERVE | MAP_LOCKED | MAP_POPULATE,
shmid_, offset);
+#else
+ void * mapping = mmap(NULL, length, PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_NORESERVE | MAP_LOCKED | MAP_POPULATE,
+ shmid_, offset);
+#endif
if (mapping == MAP_FAILED) {
string errtxt = ErrorString(errno);
logprintf(0, "Process Error: PrepareTestMem mmap64(%llx, %llx) failed. "
@@ -750,9 +762,15 @@ bool OsLayer::CpuStressWorkload() {
// Initialize array with random numbers.
for (int i = 0; i < 100; i++) {
+#ifdef HAVE_RAND_R
float_arr[i] = rand_r(&seed);
if (rand_r(&seed) % 2)
float_arr[i] *= -1.0;
+#else
+ float_arr[i] = rand();
+ if (rand() % 2)
+ float_arr[i] *= -1.0;
+#endif
}
// Calculate moving average.
diff --git a/src/sat.cc b/src/sat.cc
index bed62b7..ede951d 100644
--- a/src/sat.cc
+++ b/src/sat.cc
@@ -77,7 +77,14 @@ bool Sat::InitializeLogfile() {
// Open logfile.
if (use_logfile_) {
logfile_ = open(logfilename_,
- O_WRONLY | O_CREAT | O_DSYNC,
+#if defined(O_DSYNC)
+ O_DSYNC |
+#elif defined(O_SYNC)
+ O_SYNC |
+#elif defined(O_FSYNC)
+ O_FSYNC |
+#endif
+ O_WRONLY | O_CREAT,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (logfile_ < 0) {
printf("Fatal Error: cannot open file %s for logging\n",
@@ -1271,9 +1278,15 @@ void Sat::InitializeThreads() {
// Allocate all the nums once so that we get a single chunk
// of contiguous memory.
int *num;
+#ifdef HAVE_POSIX_MEMALIGN
int err_result = posix_memalign(
reinterpret_cast<void**>(&num),
kCacheLineSize, sizeof(*num) * num_cpus * cc_cacheline_count_);
+#else
+ num = reinterpret_cast<int*>(memalign(kCacheLineSize,
+ sizeof(*num) * num_cpus * cc_cacheline_count_));
+ int err_result = (num == 0);
+#endif
sat_assert(err_result == 0);
int cline;
diff --git a/src/sattypes.h b/src/sattypes.h
index 96bf13b..9acfaf4 100644
--- a/src/sattypes.h
+++ b/src/sattypes.h
@@ -172,7 +172,14 @@ inline bool sat_sleep(time_t seconds) {
// error_num: an errno error code
inline string ErrorString(int error_num) {
char buf[256];
+#ifdef STRERROR_R_CHAR_P
return string(strerror_r(error_num, buf, sizeof buf));
+#else
+ if (strerror_r(error_num, buf, sizeof buf))
+ return "unknown failure";
+ else
+ return string(buf);
+#endif
}
// Define handy constants here
diff --git a/src/stressapptest_config.h.in b/src/stressapptest_config.h.in
index 6ae6e5a..97f306e 100644
--- a/src/stressapptest_config.h.in
+++ b/src/stressapptest_config.h.in
@@ -20,6 +20,9 @@
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
+/* Define to 1 if you have the `ftruncate' function. */
+#undef HAVE_FTRUNCATE
+
/* Define to 1 if you have the `gettimeofday' function. */
#undef HAVE_GETTIMEOFDAY
@@ -29,24 +32,36 @@
/* Define to 1 if you have the <libaio.h> header file. */
#undef HAVE_LIBAIO_H
-/* Define to 1 if you have the <malloc.h> header file. */
-#undef HAVE_MALLOC_H
-
/* Define to 1 if you have the <memory.h> 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 `mmap64' function. */
+#undef HAVE_MMAP64
+
+/* Define to 1 if you have the `munmap' function. */
+#undef HAVE_MUNMAP
+
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
#undef HAVE_NDIR_H
/* Define to 1 if you have the <netdb.h> header file. */
#undef HAVE_NETDB_H
+/* Define to 1 if you have the `posix_memalign' function. */
+#undef HAVE_POSIX_MEMALIGN
+
/* Define to 1 if you have the <pthread.h> header file. */
#undef HAVE_PTHREAD_H
+/* Define to 1 if you have the `rand_r' function. */
+#undef HAVE_RAND_R
+
+/* Define to 1 if you have the `sched_getaffinity' function. */
+#undef HAVE_SCHED_GETAFFINITY
+
/* Define to 1 if you have the `select' function. */
#undef HAVE_SELECT
@@ -210,6 +225,9 @@
# define __restrict__
#endif
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
+
/* Define to `int' if <sys/types.h> does not define. */
#undef ssize_t
diff --git a/src/worker.cc b/src/worker.cc
index 2fab28e..2dae464 100644
--- a/src/worker.cc
+++ b/src/worker.cc
@@ -44,7 +44,9 @@
#include <sys/ioctl.h>
#include <linux/fs.h>
// For asynchronous I/O
+#ifdef HAVE_LIBAIO_H
#include <libaio.h>
+#endif
#include <sys/syscall.h>
@@ -75,11 +77,6 @@ _syscall3(int, sched_setaffinity, pid_t, pid,
unsigned int, len, cpu_set_t*, mask)
#endif
-// Linux aio syscalls.
-#if !defined(__NR_io_setup)
-#error "No aio headers inculded, please install libaio."
-#endif
-
namespace {
// Get HW core ID from cpuid instruction.
inline int apicid(void) {
@@ -147,14 +144,18 @@ static void *ThreadSpawnerGeneric(void *ptr) {
void WorkerStatus::Initialize() {
sat_assert(0 == pthread_mutex_init(&num_workers_mutex_, NULL));
sat_assert(0 == pthread_rwlock_init(&status_rwlock_, NULL));
+#ifdef _POSIX_BARRIERS
sat_assert(0 == pthread_barrier_init(&pause_barrier_, NULL,
num_workers_ + 1));
+#endif
}
void WorkerStatus::Destroy() {
sat_assert(0 == pthread_mutex_destroy(&num_workers_mutex_));
sat_assert(0 == pthread_rwlock_destroy(&status_rwlock_));
+#ifdef _POSIX_BARRIERS
sat_assert(0 == pthread_barrier_destroy(&pause_barrier_));
+#endif
}
void WorkerStatus::PauseWorkers() {
@@ -219,8 +220,10 @@ void WorkerStatus::RemoveSelf() {
AcquireNumWorkersLock();
// Decrement num_workers_ and reinitialize pause_barrier_, which we know isn't
// in use because (status != PAUSE).
+#ifdef _POSIX_BARRIERS
sat_assert(0 == pthread_barrier_destroy(&pause_barrier_));
sat_assert(0 == pthread_barrier_init(&pause_barrier_, NULL, num_workers_));
+#endif
--num_workers_;
ReleaseNumWorkersLock();
@@ -399,7 +402,11 @@ bool WorkerThread::Work() {
// mask = 13 (1101b): cpu0, 2, 3
bool WorkerThread::AvailableCpus(cpu_set_t *cpuset) {
CPU_ZERO(cpuset);
+#ifdef HAVE_SCHED_GETAFFINITY
return sched_getaffinity(getppid(), sizeof(*cpuset), cpuset) == 0;
+#else
+ return 0;
+#endif
}
@@ -409,7 +416,11 @@ bool WorkerThread::AvailableCpus(cpu_set_t *cpuset) {
// mask = 13 (1101b): cpu0, 2, 3
bool WorkerThread::CurrentCpus(cpu_set_t *cpuset) {
CPU_ZERO(cpuset);
+#ifdef HAVE_SCHED_GETAFFINITY
return sched_getaffinity(0, sizeof(*cpuset), cpuset) == 0;
+#else
+ return 0;
+#endif
}
@@ -436,7 +447,11 @@ bool WorkerThread::BindToCpus(const cpu_set_t *thread_mask) {
cpuset_format(&process_mask).c_str());
return false;
}
+#ifdef HAVE_SCHED_GETAFFINITY
return (sched_setaffinity(gettid(), sizeof(*thread_mask), thread_mask) == 0);
+#else
+ return 0;
+#endif
}
@@ -1791,7 +1806,12 @@ bool FileThread::PagePrepare() {
// Init a local buffer if we need it.
if (!page_io_) {
+#ifdef HAVE_POSIX_MEMALIGN
int result = posix_memalign(&local_page_, 512, sat_->page_length());
+#else
+ local_page_ = memalign(512, sat_->page_length());
+ int result = (local_page_ == 0);
+#endif
if (result) {
logprintf(0, "Process Error: disk thread posix_memalign "
"returned %d (fail)\n",
@@ -2358,7 +2378,12 @@ bool NetworkSlaveThread::Work() {
int64 loops = 0;
// Init a local buffer for storing data.
void *local_page = NULL;
+#ifdef HAVE_POSIX_MEMALIGN
int result = posix_memalign(&local_page, 512, sat_->page_length());
+#else
+ local_page = memalign(512, sat_->page_length());
+ int result = (local_page == 0);
+#endif
if (result) {
logprintf(0, "Process Error: net slave posix_memalign "
"returned %d (fail)\n",
@@ -2459,7 +2484,11 @@ bool CpuCacheCoherencyThread::Work() {
// Choose a datastructure in random and increment the appropriate
// member in that according to the offset (which is the same as the
// thread number.
+#ifdef HAVE_RAND_R
int r = rand_r(&seed);
+#else
+ int r = rand();
+#endif
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_])++;
@@ -2521,7 +2550,9 @@ DiskThread::DiskThread(DiskBlockTable *block_table) {
device_sectors_ = 0;
non_destructive_ = 0;
+#ifdef HAVE_LIBAIO_H
aio_ctx_ = 0;
+#endif
block_table_ = block_table;
update_block_table_ = 1;
@@ -2849,6 +2880,7 @@ bool DiskThread::DoWork(int fd) {
// Return false if the IO is not set up.
bool DiskThread::AsyncDiskIO(IoOp op, int fd, void *buf, int64 size,
int64 offset, int64 timeout) {
+#ifdef HAVE_LIBAIO_H
// Use the Linux native asynchronous I/O interface for reading/writing.
// A read/write consists of three basic steps:
// 1. create an io context.
@@ -2957,6 +2989,9 @@ bool DiskThread::AsyncDiskIO(IoOp op, int fd, void *buf, int64 size,
}
return true;
+#else // !HAVE_LIBAIO_H
+ return false;
+#endif
}
// Write a block to disk.
@@ -3104,9 +3139,14 @@ bool DiskThread::Work() {
}
// Allocate a block buffer aligned to 512 bytes since the kernel requires it
- // when using direst IO.
+ // when using direct IO.
+#ifdef HAVE_POSIX_MEMALIGN
int memalign_result = posix_memalign(&block_buffer_, kBufferAlignment,
sat_->page_length());
+#else
+ block_buffer_ = memalign(kBufferAlignment, sat_->page_length());
+ int memalign_result = (block_buffer_ == 0);
+#endif
if (memalign_result) {
CloseDevice(fd);
logprintf(0, "Process Error: Unable to allocate memory for buffers "
@@ -3116,6 +3156,7 @@ bool DiskThread::Work() {
return false;
}
+#ifdef HAVE_LIBAIO_H
if (io_setup(5, &aio_ctx_)) {
CloseDevice(fd);
logprintf(0, "Process Error: Unable to create aio context for disk %s"
@@ -3124,12 +3165,15 @@ bool DiskThread::Work() {
status_ = false;
return false;
}
+#endif
bool result = DoWork(fd);
status_ = result;
+#ifdef HAVE_LIBAIO_H
io_destroy(aio_ctx_);
+#endif
CloseDevice(fd);
logprintf(9, "Log: Completed %d (disk %s): disk thread status %d, "
diff --git a/src/worker.h b/src/worker.h
index 7aae5f2..0ec4c1d 100644
--- a/src/worker.h
+++ b/src/worker.h
@@ -26,7 +26,9 @@
#include <sys/time.h>
#include <sys/types.h>
+#ifdef HAVE_LIBAIO_H
#include <libaio.h>
+#endif
#include <queue>
#include <set>
@@ -138,9 +140,11 @@ class WorkerStatus {
enum Status { RUN, PAUSE, STOP };
void WaitOnPauseBarrier() {
+#ifdef _POSIX_BARRIERS
int error = pthread_barrier_wait(&pause_barrier_);
if (error != PTHREAD_BARRIER_SERIAL_THREAD)
sat_assert(error == 0);
+#endif
}
void AcquireNumWorkersLock() {
@@ -185,8 +189,10 @@ class WorkerStatus {
pthread_rwlock_t status_rwlock_;
Status status_;
+#ifdef _POSIX_BARRIERS
// Guaranteed to not be in use when (status_ != PAUSE).
pthread_barrier_t pause_barrier_;
+#endif
DISALLOW_COPY_AND_ASSIGN(WorkerStatus);
};
@@ -749,7 +755,9 @@ class DiskThread : public WorkerThread {
// not verified.
void *block_buffer_; // Pointer to aligned block buffer.
+#ifdef HAVE_LIBAIO_H
io_context_t aio_ctx_; // Asynchronous I/O context for Linux native AIO.
+#endif
DiskBlockTable *block_table_; // Disk Block Table, shared by all disk
// threads that read / write at the same