All Projects → AlexeyAB → Object_threadsafe

AlexeyAB / Object_threadsafe

Licence: apache-2.0
We make any object thread-safe and std::shared_mutex 10 times faster to achieve the speed of lock-free algorithms on >85% reads

Programming Languages

cpp
1120 projects
cpp11
221 projects
cpp14
131 projects

Projects that are alternatives of or similar to Object threadsafe

Atomic queue
C++ lockless queue.
Stars: ✭ 373 (+33.21%)
Mutual labels:  multithreading, lock-free, high-performance, low-latency
Concurrencyfreaks
Stars: ✭ 299 (+6.79%)
Mutual labels:  concurrency, lock-free, low-latency
Left Right
A lock-free, read-optimized, concurrency primitive.
Stars: ✭ 1,245 (+344.64%)
Mutual labels:  concurrency, multithreading, lock-free
Corium
Corium is a modern scripting language which combines simple, safe and efficient programming.
Stars: ✭ 18 (-93.57%)
Mutual labels:  high-performance, concurrency, multithreading
MultiHttp
This is a high performance , very useful multi-curl tool written in php. 一个超级好用的并发CURL工具!!!(httpful,restful, concurrency)
Stars: ✭ 79 (-71.79%)
Mutual labels:  high-performance, concurrency, multithreading
Stormpot
A fast object pool for the JVM
Stars: ✭ 267 (-4.64%)
Mutual labels:  concurrency, high-performance
thread-pool
A modern thread pool implementation based on C++20
Stars: ✭ 104 (-62.86%)
Mutual labels:  high-performance, concurrency
workerpoolxt
Concurrency limiting goroutine pool without upper limit on queue length. Extends github.com/gammazero/workerpool
Stars: ✭ 15 (-94.64%)
Mutual labels:  concurrency, multithreading
bikeshed
Lock free hierarchical work scheduler
Stars: ✭ 78 (-72.14%)
Mutual labels:  multithreading, lock-free
thread-pool
BS::thread_pool: a fast, lightweight, and easy-to-use C++17 thread pool library
Stars: ✭ 1,043 (+272.5%)
Mutual labels:  concurrency, multithreading
hatrack
Fast, multi-reader, multi-writer, lockless data structures for parallel programming
Stars: ✭ 55 (-80.36%)
Mutual labels:  high-performance, lock-free
MemoryAllocator.KanameShiki
Fast multi-threaded memory allocator
Stars: ✭ 73 (-73.93%)
Mutual labels:  multithreading, lock-free
optimistic lock coupling rs
🍋: A General Lock following paper "Optimistic Lock Coupling: A Scalable and Efficient General-Purpose Synchronization Method"
Stars: ✭ 21 (-92.5%)
Mutual labels:  concurrency, lock-free
cachegrand
cachegrand is an open-source fast, scalable and secure Key-Value store, also fully compatible with Redis protocol, designed from the ground up to take advantage of modern hardware vertical scalability, able to provide better performance and a larger cache at lower cost, without losing focus on distributed systems.
Stars: ✭ 87 (-68.93%)
Mutual labels:  high-performance, low-latency
wasm-bindgen-rayon
An adapter for enabling Rayon-based concurrency on the Web with WebAssembly.
Stars: ✭ 257 (-8.21%)
Mutual labels:  concurrency, multithreading
java-multithread
Códigos feitos para o curso de Multithreading com Java, no canal RinaldoDev do YouTube.
Stars: ✭ 24 (-91.43%)
Mutual labels:  concurrency, multithreading
theater
Actor framework for Dart. This package makes it easier to work with isolates, create clusters of isolates.
Stars: ✭ 29 (-89.64%)
Mutual labels:  concurrency, multithreading
Emitter
High performance, distributed and low latency publish-subscribe platform.
Stars: ✭ 3,130 (+1017.86%)
Mutual labels:  high-performance, low-latency
NanoLogLite
A revised version of NanoLog which writes human readable log file, and is easier to use.
Stars: ✭ 18 (-93.57%)
Mutual labels:  high-performance, low-latency
LruClockCache
A low-latency LRU approximation cache in C++ using CLOCK second-chance algorithm. Multi level cache too. Up to 2.5 billion lookups per second.
Stars: ✭ 35 (-87.5%)
Mutual labels:  high-performance, low-latency

This repository for examples of articles

How to make any object thread-safe with the speed of lock-free algorithms

safe_ptr.h contains C++ code of:

  • safe_ptr<> - make any your custom object thread-safe, even when passed to a function

  • contention_free_shared_mutex<> - 10 X times faster than std::shared_mutex

  • contfree_safe_ptr<> - make any your custom object thread-safe with the speed of lock-free algorithms


Performance, MOps Median Latency, usec

Additional contents for articles

There are examples:

There are benchmarks:


For your Pull Requests use a separate branch: https://github.com/AlexeyAB/object_threadsafe/tree/for_pull_requests

Before Pull Requests - please run all necessary benchmarks, preferably on a server CPU, such as in folders: CDS_test, Real_app_bench or benchmark - and insert images of the results charts.


  1. How to use safe_ptr<> - in the same way as std::shared_ptr<>: http://coliru.stacked-crooked.com/a/ccf634f1a5e7f991
#include <iostream>
#include <thread>
#include <vector>
#include <string>
#include <map>

#include "safe_ptr.h"


int main() { 
    sf::safe_ptr< std::map< std::string, int > > safe_map_string_int;

    std::thread t1([&]() { safe_map_string_int->emplace("apple", 1); }); 
    std::thread t2([&]() { safe_map_string_int->emplace("potato", 2); }); 
    t1.join(); t2.join();

    std::cout << "apple = " << (*safe_map_string_int)["apple"] << 
        ", potato = " << (*safe_map_string_int)["potato"] << std::endl;    
    return 0;
}

  1. How to use sf::contention_free_shared_mutex - in the same way as std::shared_mutex: http://coliru.stacked-crooked.com/a/11c191b06aeb5fb6
#include <iostream>
#include <thread>
#include <vector>

#include "safe_ptr.h"


template <typename T>
void func(T &s_m, int &a, int &b)
{
	for (size_t i = 0; i < 100000; ++i)
	{
		// x-lock for modification
		{
			s_m.lock();
			a++; 
			b++;
			s_m.unlock();
		}

		// s-lock for reading
		{
			s_m.lock_shared();
			assert(a == b);		// will never happen
			s_m.unlock_shared();
		}
	}
}

int main() {

	int a = 0;
	int b = 0;
	sf::contention_free_shared_mutex< > s_m;
	
	// 20 threads
	std::vector< std::thread > vec_thread(20);
	for (auto &i : vec_thread) i = std::move(std::thread([&]() { func(s_m, a, b); }));
	for (auto &i : vec_thread) i.join();
	
	std::cout << "a = " << a << ", b = " << b << std::endl;
	getchar();

	return 0;
}

2.1. How to use contfree_safe_ptr< std::map >: http://coliru.stacked-crooked.com/a/b78467b7a3885e5b

#include "safe_ptr.h"

sf::contfree_safe_ptr< std::map<std::string, int> > safe_map_strings_global;   // cont-free shared-mutex


template<typename T>
void func(sf::contfree_safe_ptr<T> safe_map_strings)
{
    // read-only (shared lock during access)
    sf::contfree_safe_ptr<T> const &readonly_safe_map_string = safe_map_strings;

    for (size_t i = 0; i < 100000; ++i)
    {
        // two Shared locks (recursive)
        assert(readonly_safe_map_string->at("apple") == readonly_safe_map_string->at("potato"));    

        std::lock_guard<decltype(safe_map_strings)> lock(safe_map_strings); // 1-st eXclusive lock
        safe_map_strings->at("apple") += 1;                                 // 2-nd recursive eXclusive lock
        safe_map_strings->find("potato")->second += 1;                      // 3-rd recursive eXclusive lock
    }
}

int main() {

    (*safe_map_strings_global)["apple"] = 0;
    (*safe_map_strings_global)["potato"] = 0;

    std::vector<std::thread> vec_thread(10);
    for (auto &i : vec_thread) i = std::move(std::thread([&]() { func(safe_map_strings_global); }));
    for (auto &i : vec_thread) i.join();

    std::cout << "END: potato is " << safe_map_strings_global->at("potato") <<
        ", apple is " << safe_map_strings_global->at("apple") << std::endl;


    return 0;
}

  1. High-performance usage of contfree_safe_ptr< std::map > and safe_obj<>: http://coliru.stacked-crooked.com/a/f7079aa1acc00a78
#include "safe_ptr.h"

using namespace sf;

struct field_t { int money, time; field_t(int m, int t) : money(m), time(t) {} field_t() : money(0), time(0) {} };
typedef safe_obj<field_t, spinlock_t> safe_obj_field_t;


contfree_safe_ptr< std::map<int, safe_obj_field_t> > safe_map_contfree_rowlock_global;



template<typename T>
void benchmark_safe_ptr_rowlock(T safe_map, size_t const iterations_count, size_t const container_size)
{
    const unsigned int seed = (unsigned)std::chrono::system_clock::now().time_since_epoch().count();
    std::default_random_engine generator(seed);
    std::uniform_int_distribution<size_t> index_distribution(0, container_size);
                
    enum { insert_op, delete_op, update_op, read_op };
    std::uniform_int_distribution<size_t> operation_distribution(insert_op, read_op);    // 0 - 4

    for (size_t i = 0; i < iterations_count; ++i) 
    {
        int const rnd_index = index_distribution(generator);    // 0 - container_size
        int const num_op = operation_distribution(generator);   // insert_op, update_op, delete_op, read_op

        switch (num_op) {
        case insert_op: {
            slock_safe_ptr(safe_map)->find(rnd_index);  // find for pre-cache to L1 with temprorary S-lock
            
            safe_map->emplace(rnd_index, (field_t(rnd_index, rnd_index)));  // insert with X-lock on Table
            break;
        }
        case delete_op: {
            slock_safe_ptr(safe_map)->find(rnd_index);  // find for pre-cache to L1 with temprorary S-lock
            
            size_t erased_elements = safe_map->erase(rnd_index);    // erase with X-lock on Table
        }
            break;
        case update_op: {
            auto s_safe_map = slock_safe_ptr(safe_map); // S-lock on Table
            auto it = s_safe_map->find(rnd_index);
            if (it != s_safe_map->cend()) {
                auto x_field = xlock_safe_ptr(it->second);
                x_field->money += rnd_index;   // X-lock on field, still S-lock on Table (must necessarily be)
            }
        }
            break;
        case read_op: {
            auto s_safe_map = slock_safe_ptr(safe_map); // S-lock on Table
            auto it = s_safe_map->find(rnd_index);
            if (it != s_safe_map->cend()) {
                auto s_field = slock_safe_ptr(it->second);
                volatile int money = s_field->money;   // S-lock on field, still S-lock on Table (must be)
                // volatile here only to avoid optimization for unused money-variable
            }
        }
            break;
        default: std::cout << "\n wrong way! \n";  break;
        }
    }
}


int main() {

    const size_t iterations_count = 100000;     // operations of data exchange between threads
    const size_t container_size = 100000;       // elements in container
    std::vector<std::thread> vec_thread(8);     // threads number
    std::cout << "Threads: " << vec_thread.size() << std::endl;

    std::cout << "Testing safe<map,contf>rowlock... \n"; 
    for (auto &i : vec_thread) i = std::move(std::thread([&]() {
        benchmark_safe_ptr_rowlock(safe_map_contfree_rowlock_global, iterations_count, container_size);
    }));
    for (auto &i : vec_thread) i.join();

    std::cout << "Successfully completed." << std::endl;
    return 0;
}
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].