diff options
author | Scott Anderson <saa@android.com> | 2012-02-17 14:25:17 -0800 |
---|---|---|
committer | Scott Anderson <saa@android.com> | 2012-04-10 11:13:48 -0700 |
commit | 8f1c60d605d31447b4f9ccf86029790bed3fb3f3 (patch) | |
tree | 8f7a30b762f94b30a4f615d43a9ce07b5acc0370 | |
parent | b0114cb9f332db144f65291211ae65f7f0e814e6 (diff) | |
download | stressapptest-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-x | configure | 324 | ||||
-rw-r--r-- | configure.ac | 73 | ||||
-rw-r--r-- | src/os.cc | 18 | ||||
-rw-r--r-- | src/sat.cc | 15 | ||||
-rw-r--r-- | src/sattypes.h | 7 | ||||
-rw-r--r-- | src/stressapptest_config.h.in | 24 | ||||
-rw-r--r-- | src/worker.cc | 56 | ||||
-rw-r--r-- | src/worker.h | 8 |
8 files changed, 325 insertions, 200 deletions
@@ -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 @@ -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. @@ -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 |