Skip to content
Snippets Groups Projects
Commit 8e06e40e authored by Recolic Keghart's avatar Recolic Keghart
Browse files

[DO NOT BUILD] save my work

parent 9a6d0c7b
No related branches found
No related tags found
No related merge requests found
#ifndef _RLIB_EASY_CONDITION_VAR
#define _RLIB_EASY_CONDITION_VAR 1
#include <condition_variable>
#include <mutex>
#include <atomic>
#include <rlib/class_decorator.hpp>
namespace rlib {
class easy_condition_variable : rlib::noncopyable {
public:
easy_condition_variable()
: stdcv(), stdcv_mutex(), notify_count(0) {}
void notify_one() {
stdcv.notify_one();
}
void notify_all() {
stdcv.notify_all();
}
void wait() {
std::unique_lock<std::mutex> lk(stdcv_mutex);
stdcv.wait(lk, [this]{return notify_count.load() > 0;});
lk.unlock();
}
template< class Rep, class Period >
bool wait_for(const std::chrono::duration<Rep, Period>& rel_time) {
std::unique_lock<std::mutex> lk(stdcv_mutex);
bool ret = stdcv.wait_for(lk, rel_time, [this]{return notify_count.load() > 0;});
lk.unlock();
return ret;
}
template< class Clock, class Duration >
bool wait_until(const std::chrono::time_point<Clock, Duration>& timeout_time) {
std::unique_lock<std::mutex> lk(stdcv_mutex);
bool ret = stdcv.wait_until(lk, timeout_time, [this]{return notify_count.load() > 0;});
lk.unlock();
return ret;
}
private:
std::condition_variable stdcv;
std::mutex stdcv_mutex;
std::atomic<int> notify_count;
};
} // namespace rlib
#endif
\ No newline at end of file
......@@ -46,6 +46,10 @@ namespace rlib {
(*used)--;
return false;
}
size_t objects_should_alloc(const size_t inuse_objects, const size_t avail_objects) {
return avail_objects < size ? size - avail_objects : 0;
}
private:
const size_t size;
std::unique_ptr<std::atomic<size_t> > used;
......@@ -116,7 +120,7 @@ namespace rlib {
typename buffer_t::iterator elem_iter(which);
elem_iter.get_extra_info() = true; // mark as free.
new_obj_ready = true;
--curr_size;
--inuse_objects;
} // lock released.
borrow_cv.notify_one();
}
......@@ -125,21 +129,31 @@ namespace rlib {
reconstruct_impl(which, std::make_index_sequence<sizeof...(_bound_construct_args_t)>());
}
size_t inuse_size() const {
return inuse_objects;
}
size_t size() const {
return curr_size;
// total size. inuse + free.
return inuse_objects + free_list.size();
}
protected:
buffer_t buffer; // list<obj_t obj, bool is_free>
private:
std::list<obj_t *> free_list;
std::mutex buffer_mutex; // mutex for buffer and free_list
std::tuple<_bound_construct_args_t ...> _bound_args;
size_t curr_size = 0;
size_t inuse_objects = 0;
policy_t policy;
std::list<obj_t *> free_list;
std::mutex buffer_mutex;
std::condition_variable borrow_cv;
std::condition_variable borrow_cv; // use buffer_mutex on notifying alloc event.
volatile bool new_obj_ready = false;
void notify_new_object_allocated(size_t how_many) {
new_obj_ready = true;
for(auto cter = 0; cter < how_many; ++cter)
borrow_cv.notify_one();
}
// try_borrow_one without lock.
obj_t *do_try_borrow_one() {
......@@ -157,7 +171,7 @@ namespace rlib {
typename buffer_t::iterator elem_iter(result);
elem_iter.get_extra_info() = false; // mark as busy.
new_obj_ready = false;
++curr_size;
++inuse_objects;
return result;
}
return nullptr;
......@@ -177,6 +191,33 @@ namespace rlib {
inline void new_obj_to_buffer() {
new_obj_to_buffer_impl(std::make_index_sequence<sizeof...(_bound_construct_args_t)>());
}
std::mutex alloc_thread_notify_mutex;
std::condition_variable alloc_thread_notify_cv;
volatile bool alloc_thread_should_trigger = false;
void alloc_thread_func() {
// A new thread to alloc new objects basing on policy.
while(true) {
std::unique_lock<std::mutex> lk(alloc_thread_notify_mutex);
alloc_thread_notify_cv.wait(lk, [this]{return this->alloc_thread_should_trigger;});
// serial area.
lk.unlock();
auto should_alloc = policy.objects_should_alloc(inuse_size(), size());
{
std::lock_guard<std::mutex> _l(buffer_mutex);
for(auto cter = 0; cter < should_alloc; ++cter) {
// Alloc a new object.
new_obj_to_buffer();
free_list.push_back(&*--buffer.end());
}
}
if(should_alloc > 0) {
}
}
}
};
}
......
......@@ -94,3 +94,12 @@ TEST_CASE("infinite dynamic object pool") {
REQUIRE(inf_pool.size() == 1+test_rounds);
}
TEST_CASE("fixed object pool parallel test") {
size_t pool_size = 8;
const auto arg1 = 666;
const auto arg2 = string("fuck you");
rlib::object_pool<rlib::object_pool_policy_fixed, pooled_obj_t, decltype(arg1), decltype(arg2)>
fixed_pool(rlib::object_pool_policy_fixed(pool_size), arg1, arg2);
}
#define CATCH_CONFIG_MAIN
#include <catch.hpp>
#include <rlib/condition_variable.hpp>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment