diff --git a/README.md b/README.md index ab3564f..797294d 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,24 @@ `c++11` `c++14` `c++17` focused libraries ("head-only" big law is good!) for personal use. + +|item| describe | +|-|-| +|cfg| a hash table| +|channel | a Rust-like mpsc channel implementation based on lock-free mpsc (multi-producer single-consumer) queue| +|clp | a very simple commandline parser for C++17's features test | +| crypt | I don't know..| +| fake_variant | a tuple-like class | +|file_sort | sort numbers in a big file (bitset and divide-conquer) | +|logging | a log library based on mpsc queue | +|loop_per_thread | a test for loop per thread paradigm | +|rbtree | a red-black implementation | +|signal | a simple signal-slot implementation | +|string_ext| an extended std::string | +|threadpool | a simple thread pool implementation via std::thread and a lock-based task queue| +|variant | a variant implementation for C++11 | +| typelist.cpp | a loki-like typelist implemented by modern C++ | + ### LICENSE [GPLv3](./LICENSE)([with exception](https://gcc.gnu.org/onlinedocs/libstdc++/manual/license.html)) diff --git a/channel/README.md b/channel/README.md index e4e6a4f..c40344c 100644 --- a/channel/README.md +++ b/channel/README.md @@ -3,3 +3,41 @@ A C++ implementation of **MPSC** (multi-producer single-consumer) [channel](./channel.h). see [mpsc.rs](./mpsc.rs). + +----- +`rustc -C opt-level=3 mpsc.rs -o a.out +` [rustc 1.20.0-nightly] +``` +./a.out 10000000 +thread 0 done +thread 2 done +thread 1 done +thread 0 => 10000000 +thread 1 => 10000000 +thread 2 => 10000000 +receiver done. +3.118793157 +``` +`g++ -std=c++17 test.cpp -pthread -O3` [g++ (SUSE Linux) 7.1.1 20170629] +``` +thread 0 done +thread 2 done +thread 1 done +thread 0 => 10000000 +thread 1 => 10000000 +thread 2 => 10000000 +receiver done. +3.111892014 +``` +`g++ -std=c++17 test.cpp -pthread -O3 -DJEMALLOC -ljemalloc` [g++ (SUSE Linux) 7.1.1 20170629] +``` +./a.out 10000000 +thread 2 done +thread 0 done +thread 1 done +thread 0 => 10000000 +thread 1 => 10000000 +thread 2 => 10000000 +receiver done. +2.148938502 +``` diff --git a/channel/channel.h b/channel/channel.h index d61b15d..3f4c87d 100644 --- a/channel/channel.h +++ b/channel/channel.h @@ -147,9 +147,8 @@ class Queue public: Queue() - : size_(0), - head_(alloc()), - tail_(head_.load()) + : head_(alloc()), + tail_(head_.load()) { auto tmp = head_.load(); tmp->next.store(nullptr); @@ -174,12 +173,7 @@ class Queue bool empty() const { - return size_ == 0; - } - - size_t unsafe_size() const - { - return size_.load(); + return tail_->next.load(std::memory_order_acquire) == nullptr; } void push(const T& data) @@ -189,7 +183,6 @@ class Queue tmp->next.store(nullptr, std::memory_order_relaxed); auto old_head = head_.exchange(tmp, std::memory_order_acq_rel); old_head->next.store(tmp, std::memory_order_release); - size_ += 1; } void push(T&& data) @@ -199,7 +192,6 @@ class Queue tmp->next.store(nullptr, std::memory_order_relaxed); auto old_head = head_.exchange(tmp, std::memory_order_acq_rel); old_head->next.store(tmp, std::memory_order_release); - size_ += 1; } bool try_pop(T& data) @@ -210,12 +202,10 @@ class Queue data = std::move(next->data); dealloc(tail_); tail_ = next; - size_ -= 1; return true; } private: - std::atomic size_; std::atomic head_; Node* tail_; }; diff --git a/clp/clp.h b/clp/clp.h index cdce8f2..f7f1c1a 100644 --- a/clp/clp.h +++ b/clp/clp.h @@ -201,7 +201,7 @@ namespace nm return; } // get key - if(iter->find_first_of(delim) != iter->npos && *iter != "--") + if(iter->find(delim) != iter->npos && *iter != "--") { tmp = iter->substr(delim.length()); has_key = true; @@ -236,7 +236,7 @@ namespace nm } } // no value - else if(iter->find_first_of(delim) < delim.size()) + else if(iter->find(delim) < delim.size()) { --iter; c_.emplace(tmp); diff --git a/loop_per_thread/server.cpp b/loop_per_thread/server.cpp index 4c8eb6e..5c94dab 100644 --- a/loop_per_thread/server.cpp +++ b/loop_per_thread/server.cpp @@ -174,14 +174,13 @@ class Session : public std::enable_shared_from_this //std::cerr << ec.message() << std::endl; return; } - buf_.consume(bytes); processing(); }); } void processing() { - async_write(socket_, boost::asio::buffer("pong\n"), + async_write(socket_, buf_, [this, self = shared_from_this()](const error_code& ec, size_t) { if(ec) diff --git a/typelist.cpp b/typelist.cpp index 0a70ed4..f1e2d67 100644 --- a/typelist.cpp +++ b/typelist.cpp @@ -219,7 +219,6 @@ namespace nm template constexpr static void call(F) {} }; - // common idiom CRTP template struct overloaded : Args... { using Args::operator()...;