diff --git a/ChangeLog b/ChangeLog index e73cd37d7..81eb0172e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,7 +15,10 @@ * mkvmerge: new feature: Use the posix_fadvise function on *nix systems. This results in a considerable speed up for the whole - muxing process. + muxing process. As the function call seems to be buggy on at least + Linux kernels 2.4.x it can be disabled completely during + configure. It will only be used on Linux with a kernel from the + 2.6.x series or newer. 2005-02-01 Moritz Bunkus diff --git a/configure.in b/configure.in index 53b103fa3..8fb499900 100644 --- a/configure.in +++ b/configure.in @@ -292,6 +292,11 @@ fi dnl dnl Check for posix_fadvise and its definitions dnl +AC_ARG_ENABLE(posix-fadvise, + [ --disable-posix-fadvise do not use posix_fadvise (auto)],, + [enable_posix_fadvise=yes]) + +if test x"$enable_posix_fadvise" != "xno" ; then AC_CACHE_CHECK([for posix_fadvise], [ac_cv_posix_fadvise],[ ac_cv_posix_fadvise="no" AC_LANG_PUSH(C++) @@ -306,7 +311,7 @@ dnl if test x"$ac_cv_posix_fadvise" = "xyes" ; then AC_DEFINE([HAVE_POSIX_FADVISE], 1, [define if posix_advise and its definitions are available]) fi - +fi dnl dnl Test for libiconv diff --git a/src/common/mm_io.cpp b/src/common/mm_io.cpp index d70e4c11f..18d5371ee 100644 --- a/src/common/mm_io.cpp +++ b/src/common/mm_io.cpp @@ -19,6 +19,7 @@ #include #if HAVE_POSIX_FADVISE # include +# include #endif #include #include @@ -41,6 +42,7 @@ using namespace std; # if HAVE_POSIX_FADVISE static const unsigned long read_using_willneed = 16 * 1024 * 1024; static const unsigned long write_before_dontneed = 8 * 1024 * 1024; +bool mm_file_io_c::use_posix_fadvise = false; # endif mm_file_io_c::mm_file_io_c(const string &path, @@ -93,8 +95,9 @@ mm_file_io_c::mm_file_io_c(const string &path, throw error_c(mxsprintf("Error opening file %s", path.c_str())); # if HAVE_POSIX_FADVISE - if (0 != posix_fadvise(fileno((FILE *)file), 0, read_using_willneed, - advise)) + if (use_posix_fadvise && + (0 != posix_fadvise(fileno((FILE *)file), 0, read_using_willneed, + advise))) mxerror("mm_file_io_c: Could not fadvise file '%s' (errno = %d, %s)\n", path.c_str(), errno, strerror(errno)); # endif @@ -133,7 +136,7 @@ mm_file_io_c::write(const void *buffer, # if HAVE_POSIX_FADVISE write_count += bwritten; - if (write_count > write_before_dontneed) { + if (use_posix_fadvise && (write_count > write_before_dontneed)) { uint64 pos = getFilePointer(); write_count = 0; if (0 != posix_fadvise(fileno((FILE *)file), 0, pos, POSIX_FADV_DONTNEED)) @@ -153,7 +156,7 @@ mm_file_io_c::read(void *buffer, bread = fread(buffer, 1, size, (FILE *)file); # if HAVE_POSIX_FADVISE - if (bread >= 0) { + if (use_posix_fadvise && (0 <= bread)) { read_count += bread; if (read_count > read_using_willneed) { uint64 pos = getFilePointer(); @@ -189,6 +192,31 @@ mm_file_io_c::truncate(int64_t pos) { return ftruncate(fileno((FILE *)file), pos); } +/** \brief OS and kernel dependant setup + + The \c posix_fadvise call can improve read/write performance a lot. + Unfortunately it is pretty new and a buggy on a couple of Linux kernels + in the 2.4.x series. So only enable its usage for 2.6.x kernels. +*/ +void +mm_file_io_c::setup() { +# if HAVE_POSIX_FADVISE + struct utsname un; + + use_posix_fadvise = false; + if ((0 == uname(&un)) && !strcasecmp(un.sysname, "Linux")) { + vector versions; + int major, minor; + + versions = split(un.release, "."); + if ((2 <= versions.size()) && + parse_int(versions[0], major) && parse_int(versions[1], minor) && + ((2 < major) || (6 <= minor))) + use_posix_fadvise = true; + } +# endif // HAVE_POSIX_FADVISE +} + #else // SYS_WINDOWS HANDLE @@ -359,6 +387,10 @@ mm_file_io_c::truncate(int64_t pos) { return -1; } +void +mm_file_io_c::setup() { +} + #endif // SYS_UNIX mm_file_io_c::~mm_file_io_c() { diff --git a/src/common/mm_io.h b/src/common/mm_io.h index 334ad83df..05e10160d 100644 --- a/src/common/mm_io.h +++ b/src/common/mm_io.h @@ -91,6 +91,7 @@ protected: #endif #if HAVE_POSIX_FADVISE unsigned long read_count, write_count; + static bool use_posix_fadvise; #endif string file_name; void *file; @@ -111,6 +112,8 @@ public: } virtual int truncate(int64_t pos); + + static void setup(); }; class MTX_DLL_API mm_proxy_io_c: public mm_io_c { diff --git a/src/extract/mkvextract.cpp b/src/extract/mkvextract.cpp index da4b3ed7a..2d98ea240 100644 --- a/src/extract/mkvextract.cpp +++ b/src/extract/mkvextract.cpp @@ -379,6 +379,7 @@ main(int argc, textdomain("mkvtoolnix"); #endif + mm_file_io_c::setup(); srand(time(NULL)); utf8_init(""); diff --git a/src/info/mkvinfo.cpp b/src/info/mkvinfo.cpp index 525a7e0ff..65bff41dc 100644 --- a/src/info/mkvinfo.cpp +++ b/src/info/mkvinfo.cpp @@ -1964,6 +1964,7 @@ setup() { textdomain("mkvtoolnix"); #endif + mm_file_io_c::setup(); cc_local_utf8 = utf8_init(""); init_cc_stdio(); diff --git a/src/merge/output_control.cpp b/src/merge/output_control.cpp index 3de9a374a..0a78638cd 100644 --- a/src/merge/output_control.cpp +++ b/src/merge/output_control.cpp @@ -1921,6 +1921,7 @@ setup() { signal(SIGINT, sighandler); #endif + mm_file_io_c::setup(); srand(time(NULL)); cc_local_utf8 = utf8_init(""); init_cc_stdio(); diff --git a/src/mmg/mmg.cpp b/src/mmg/mmg.cpp index d239fcc0c..ac39e378f 100644 --- a/src/mmg/mmg.cpp +++ b/src/mmg/mmg.cpp @@ -1872,6 +1872,7 @@ mmg_app::OnInit() { uint32_t i; wxString k, v; + mm_file_io_c::setup(); cc_local_utf8 = utf8_init(""); xml_element_map_init();