diff --git a/README-DPDK.md b/README-DPDK.md index 39b1c5d10c..79d8862bc6 100644 --- a/README-DPDK.md +++ b/README-DPDK.md @@ -4,11 +4,11 @@ Seastar and DPDK Seastar uses the Data Plane Development Kit to drive NIC hardware directly. This provides an enormous performance boost. -To enable DPDK, specify `--enable-dpdk` to `./configure.py`, and `--dpdk-pmd 1` as a +To enable DPDK, specify `--enable-dpdk` to `./configure.py`, and `--dpdk-pmd` as a run-time parameter. This will use the DPDK package provided as a git submodule with the seastar sources. -To use your own seld-compiled DPDK package, follow this procedure: +To use your own self-compiled DPDK package, follow this procedure: 1. Setup host to compile DPDK: - Ubuntu diff --git a/configure.py b/configure.py index b4d7a024e3..456f50c45d 100755 --- a/configure.py +++ b/configure.py @@ -509,7 +509,7 @@ deps = { 'apps/httpd/httpd': ['apps/httpd/demo.json', 'apps/httpd/main.cc'] + http + libnet + core, 'apps/memcached/memcached': ['apps/memcached/memcache.cc'] + memcache_base, 'tests/memcached/test_ascii_parser': ['tests/memcached/test_ascii_parser.cc'] + memcache_base + boost_test_lib, - 'tests/fileiotest': ['tests/fileiotest.cc'] + core, + 'tests/fileiotest': ['tests/fileiotest.cc'] + core + boost_test_lib, 'tests/directory_test': ['tests/directory_test.cc'] + core, 'tests/linecount': ['tests/linecount.cc'] + core, 'tests/echotest': ['tests/echotest.cc'] + core + libnet, diff --git a/core/file.hh b/core/file.hh index e1ab3649ad..991b47ef4c 100644 --- a/core/file.hh +++ b/core/file.hh @@ -104,9 +104,8 @@ public: inline std::unique_ptr make_file_impl(int fd) { - struct stat st; - ::fstat(fd, &st); - if (S_ISBLK(st.st_mode)) { + auto r = ::ioctl(fd, BLKGETSIZE); + if (r != -1) { return std::unique_ptr(new blockdev_file_impl(fd)); } else { return std::unique_ptr(new posix_file_impl(fd)); diff --git a/core/fstream.cc b/core/fstream.cc index c375a75c19..729dfa77f9 100644 --- a/core/fstream.cc +++ b/core/fstream.cc @@ -92,6 +92,10 @@ public: return temporary_buffer::aligned(file::dma_alignment, size); } virtual future<> put(temporary_buffer buf) override { + // put() must usually be of chunks multiple of file::dma_alignment. + // Only the last part can have an unaligned length. If put() was + // called again with an unaligned pos, we have a bug in the caller. + assert(!(_pos & (file::dma_alignment - 1))); bool truncate = false; auto pos = _pos; _pos += buf.size(); @@ -141,6 +145,6 @@ output_stream make_file_output_stream(lw_shared_ptr f, size_t buffer } output_stream make_file_output_stream(lw_shared_ptr f, file_output_stream_options options) { - return output_stream(file_data_sink(std::move(f), options), options.buffer_size); + return output_stream(file_data_sink(std::move(f), options), options.buffer_size, true); } diff --git a/core/shared_ptr.hh b/core/shared_ptr.hh index 9e47c1c0d4..56219a07ea 100644 --- a/core/shared_ptr.hh +++ b/core/shared_ptr.hh @@ -432,6 +432,13 @@ public: T* get() const noexcept { return _p; } + long use_count() const noexcept { + if (_b) { + return _b->count; + } else { + return 0; + } + } template struct make_helper; diff --git a/test.py b/test.py index 9afc2e36c5..640eb3d9f0 100755 --- a/test.py +++ b/test.py @@ -34,6 +34,7 @@ boost_tests = [ 'foreign_ptr_test', 'semaphore_test', 'shared_ptr_test', + 'fileiotest', 'urchin/bytes_ostream_test', 'urchin/types_test', 'urchin/keys_test', diff --git a/tests/fileiotest.cc b/tests/fileiotest.cc index 19b289a56f..08b2ecfd2a 100644 --- a/tests/fileiotest.cc +++ b/tests/fileiotest.cc @@ -16,12 +16,14 @@ * under the License. */ /* - * Copyright (C) 2014 Cloudius Systems, Ltd. + * Copyright (C) 2014-2015 Cloudius Systems, Ltd. */ -#include +#include "tests/test-utils.hh" + +#include "core/semaphore.hh" +#include "core/file.hh" #include "core/reactor.hh" -#include "core/app-template.hh" struct file_test { file_test(file&& f) : f(std::move(f)) {} @@ -30,41 +32,36 @@ struct file_test { semaphore par = { 1000 }; }; -int main(int ac, char** av) { - app_template app; - - return app.run(ac, av, [&app] { - static constexpr auto max = 10000; - engine().open_file_dma("testfile.tmp", open_flags::rw | open_flags::create).then([] (file f) { - auto ft = new file_test{std::move(f)}; - for (size_t i = 0; i < max; ++i) { - ft->par.wait().then([ft, i] { - auto wbuf = allocate_aligned_buffer(4096, 4096); - std::fill(wbuf.get(), wbuf.get() + 4096, i); - auto wb = wbuf.get(); - ft->f.dma_write(i * 4096, wb, 4096).then( - [ft, i, wbuf = std::move(wbuf)] (size_t ret) mutable { - assert(ret == 4096); - auto rbuf = allocate_aligned_buffer(4096, 4096); - auto rb = rbuf.get(); - ft->f.dma_read(i * 4096, rb, 4096).then( - [ft, i, rbuf = std::move(rbuf), wbuf = std::move(wbuf)] (size_t ret) mutable { - assert(ret == 4096); - bool eq = std::equal(rbuf.get(), rbuf.get() + 4096, wbuf.get()); - assert(eq); - ft->sem.signal(1); - ft->par.signal(); - }); +SEASTAR_TEST_CASE(test1) { + // Note: this tests generates a file "testfile.tmp" with size 4096 * max (= 40 MB). + static constexpr auto max = 10000; + return open_file_dma("testfile.tmp", open_flags::rw | open_flags::create).then([] (file f) { + auto ft = new file_test{std::move(f)}; + for (size_t i = 0; i < max; ++i) { + ft->par.wait().then([ft, i] { + auto wbuf = allocate_aligned_buffer(4096, 4096); + std::fill(wbuf.get(), wbuf.get() + 4096, i); + auto wb = wbuf.get(); + ft->f.dma_write(i * 4096, wb, 4096).then( + [ft, i, wbuf = std::move(wbuf)] (size_t ret) mutable { + BOOST_REQUIRE(ret == 4096); + auto rbuf = allocate_aligned_buffer(4096, 4096); + auto rb = rbuf.get(); + ft->f.dma_read(i * 4096, rb, 4096).then( + [ft, i, rbuf = std::move(rbuf), wbuf = std::move(wbuf)] (size_t ret) mutable { + BOOST_REQUIRE(ret == 4096); + BOOST_REQUIRE(std::equal(rbuf.get(), rbuf.get() + 4096, wbuf.get())); + ft->sem.signal(1); + ft->par.signal(); }); }); - } - ft->sem.wait(max).then([ft] () mutable { - return ft->f.flush(); - }).then([ft] () mutable { - std::cout << "done\n"; - delete ft; - engine().exit(0); }); + } + return ft->sem.wait(max).then([ft] () mutable { + return ft->f.flush(); + }).then([ft] () mutable { + std::cout << "done\n"; + delete ft; }); }); }