Header-only library for multithreaded programming

Overview

CsLibGuarded

Introduction

The CsLibGuarded library is a standalone header only library for multithreaded programming.

This library provides templated classes which prevent race conditions by controlling access to shared data. Existing multithreading primitives like mutexes and locks are only bound to the protected data by conventions. This makes it very easy to introduce bugs in your code by forgetting to use the right locks before accessing a block of data. The idea of this library is to tie the data and the locks in a type safe interface that only allows correct usage.

System Requirements

To use CsLibGuarded you will need a C++17 compiler which fully supports the C++17 standard library.

CMake is only for building and running the unit test suite. This library has been tested with clang thread sanitizer, multiple code reviews, and production software.

Documentation

Class level documentation for CsLibGuarded is available on the CopperSpice website:

www.copperspice.com/docs/cs_libguarded/index.html

Presentations

Our YouTube channel contains videos about modern C++, graphics, build systems, CopperSpice, DoxyPress, and other topics related to software development.

https://www.youtube.com/copperspice

Multiple videos discussing CsLibGuarded and multithreading can be found on the following page:

www.copperspice.com/presentations.html

Authors / Contributors

  • Ansel Sermersheim
  • Barbara Geller
  • Casey Bodley
  • Jan Wilmans
  • Eric Lemanissier

License

This library is released under the BSD 2-clause license. For more information refer to the LICENSE file provided with this project.

References

Comments
  • On visual studio 2013 this fails to compile

    On visual studio 2013 this fails to compile

    #include "libguarded/guarded.hpp"
    
    struct Foo
    {
        int value;
    };
    
    int main()
    {
        libguarded::guarded<Foo> m_foo;
        auto lock = m_foo.lock();
        return 0;
    }
    
    1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\memory(1377): error C2280: 'std::unique_lock<M>::unique_lock(const std::unique_lock<M> &)' : attempting to reference a deleted function
    1>          with
    1>          [
    1>              M=std::mutex
    1>          ]
    1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\mutex(285) : see declaration of 'std::unique_lock<M>::unique_lock'
    1>          with
    1>          [
    1>              M=std::mutex
    1>          ]
    1>          This diagnostic occurred in the compiler generated function 'libguarded::guarded<Foo,std::mutex>::deleter::deleter(const libguarded::guarded<Foo,std::mutex>::deleter &)'
    
    opened by janwilmans 11
  • deleters not move_assignable

    deleters not move_assignable

    I ran into a situation where I needed to be able to unlock a shared_guarded object for a short time while a callback was called.

    the callback could in principle call other functions that would trigger the same lock, so I couldn't have the lock be engaged while the callback was executing.

    But this was executing in a loop so the lock needed to reengaged after the callback finished.
    an unlock() function on the handle would be really nice but that would require the handle be a full class instead of a unique_ptr, so I settled for setting the handle to nullptr then calling lock again.

    This generated a compile error as the use of M & m_deleter_mutex; is not move assignable, thus the deleter class itself is not move_assignable and the handle is not move_assignable, and there was no way to have a lock reassigned to an existing variable.

    My solution was to change the deleter class to store M * instead of M & and change the unlock call to use -> instead of . and the constructor to store &mutex instead. This allowed the handle to be move_assignable and at least some work around to temporary unlocking.

    The same issue would be true for guarded and ordered_guarded and probably others as well. this the cost of course is that now deleter has a pointer instead of a reference and could not be zero size, but there had to be some mechanism for temporary disengaging the lock otherwise the guarded classes are unusable for a number of purposes.

    There are a variety of other alternatives, but the issue is that there is no means of temporarily suspending a lock in a conditional branch.

    opened by phlptp 3
  • Update README.md

    Update README.md

    After getting the question: so what is libguarded useful for, reading the github description it looks like a wrapper for std::mutex, but I dont get the point. I thought I would take a stab at a more to the point description. I hope you like it :)

    opened by janwilmans 3
  • rcu: extend custom allocator support for rcu_list

    rcu: extend custom allocator support for rcu_list

    compile-tested only, but submitting for early review

    adds an allocate_unique() with associated deleter for use when exception safety is needed adds a separate m_zombie_alloc for zombie list nodes implements rcu_list(const Alloc &alloc) constructor

    opened by cbodley 3
  • rcu_list::emplace has no implementation

    rcu_list::emplace has no implementation

    The implementation of this method is missing! https://github.com/copperspice/cs_libguarded/blob/f16f2da5934adfe22a04c68340e49ecc7d3fd1f0/src/cs_rcu_list.h#L101

    opened by Ozomahtli 2
  • Trying to use shared_guarded.hpp  with C++17

    Trying to use shared_guarded.hpp with C++17

    The file has a HAVE_CXX14 define required - can this be updated otherwise I get incomplete type warnings.

    I ended up just editing the file and changing the #if to #ifndef

    opened by jogster 2
  • libguarded 1.2.0

    libguarded 1.2.0

    Current cmake file indicates 1.2.0 but there is only one tag on this repository which is nearly 4 years old: 1.1.0 Do you expect to release a new version of libguarded at some point ?

    opened by ericLemanissier 1
  • Prefer '*.hpp' over '*.h' (opionated)

    Prefer '*.hpp' over '*.h' (opionated)

    TL;DR:

    Please revert https://github.com/copperspice/cs_libguarded/commit/98b9c17e76b9dc639f2936146e2201f52c5b2f44

    Discussion

    IIRC there were really good reasons to have C++ header files end with .hpp rather than .h. Some had to do with IDE discriminating between C and C++. I believe the Boost Community went through this discussion some decades ago, but I can't find the original discussion quickly. Please find other opinions below

    Pro

    • https://stackoverflow.com/questions/152555/h-or-hpp-for-your-class-definitions
    • https://www.boost.org/users/faq.html

      Why do Boost headers have a .hpp suffix rather than .h or none at all? File extensions communicate the "type" of the file, both to humans and to computer programs. The '.h' extension is used for C header files, and therefore communicates the wrong thing about C++ header files. Using no extension communicates nothing and forces inspection of file contents to determine type. Using '.hpp' unambiguously identifies it as C++ header file, and works well in actual practice. (Rainer Deyke)

    • https://llvm.org/docs/CodingStandards.html#file-headers

    Contra

    opened by daixtrose 1
  • surprising directory structure

    surprising directory structure

    Compared to other C++ libraries like e.g. range-v3 this repository does not follow the best practice to avoid name clashes by putting headers into a directory that corresponds to the library name. So it is not possible to write

    #include <cs_libguarded/some_header.hpp>
    

    I propose to change the directory structure and CMake files such that there is a directory structure similar to

    ├── include
    │   └── cs_libguarded
    │       ├── header_1.hpp
    │       ├── header_2.hpp
    │       ├── ...
    │       └── header_N.hpp
    ├── README.md
    ├── src
    │   ├── maybe_implementation_for_header_1.cpp
    │   └── etc.cpp
    └── test
        ├── CMakeLists.txt
        ├── test_1.cpp
        ├── test_main.cpp
        └── test_N.cpp
    
    opened by daixtrose 1
  • Simplify std::enable_if use with decltype(auto)

    Simplify std::enable_if use with decltype(auto)

    Great library and fantastic work! Here is a small change to reduce lines of code using decltype(auto) if you are interested. I only tested it on Linux (arch) but am sure it will work on any C++14 compliant compiler :crossed_fingers: .

    opened by zabereer 1
  • Installation cannot find header file

    Installation cannot find header file

    Hello,

    I'm trying to install the library on Linux. The compilation runs fine, but when I try to install it ('sudo make install'), installation fails with the message:

    Install the project...
    -- Install configuration: ""
    CMake Error at cmake_install.cmake:41 (file):
      file INSTALL cannot find
      "/home/user/Downloads/sources/cs_libguarded/src/test_cow.hpp": No such
      file or directory.
    

    Am I doing something wrong?

    opened by j-silver 1
  • - Unnecessary Lock type parameter removed from shared_guarded

    - Unnecessary Lock type parameter removed from shared_guarded

    • Unnecessary Lock type parameter removed from shared_guarded. For the shared use-case at the moment I do not see any other valid option than the shared_lock.

    • Unnecessary lock check removed in the handler deleter: null unique_ptr does not call the deleter (https://en.cppreference.com/w/cpp/memory/unique_ptr/%7Eunique_ptr), so the conditional statement there is always true.

    • Simplified the invalid handle related code: with default constructible unique_ptr deleter, the invalid handle is easier (and maybe cheaper) to generate

    opened by ruszkait 1
Owner
CopperSpice
CopperSpice
EAThread - EAThread implements a unified cross-platform interface for multithreaded programming.

EAThread EAThread implements a unified cross-platform interface for multithreaded programming on various platforms. Documentation Please see Introduct

Electronic Arts 259 Dec 20, 2022
A easy to use multithreading thread pool library for C. It is a handy stream like job scheduler with an automatic garbage collector. This is a multithreaded job scheduler for non I/O bound computation.

A easy to use multithreading thread pool library for C. It is a handy stream-like job scheduler with an automatic garbage collector for non I/O bound computation.

Hyoung Min Suh 12 Jun 4, 2022
A header-only C++ library for task concurrency

transwarp Doxygen documentation transwarp is a header-only C++ library for task concurrency. It allows you to easily create a graph of tasks where eve

Christian Blume 592 Dec 19, 2022
C++20's jthread for C++11 and later in a single-file header-only library

jthread lite: C++20's jthread for C++11 and later A work in its infancy. Suggested by Peter Featherstone. Contents Example usage In a nutshell License

Martin Moene 50 Dec 8, 2022
Header-Only C++20 Coroutines library

CPP20Coroutines Header-Only C++20 Coroutines library This repository aims to demonstrate the capabilities of C++20 coroutines. generator Generates val

null 16 Aug 15, 2022
Portable header-only C++ low level SIMD library

libsimdpp libsimdpp is a portable header-only zero-overhead C++ low level SIMD library. The library presents a single interface over SIMD instruction

Povilas Kanapickas 1.1k Dec 13, 2022
DwThreadPool - A simple, header-only, dependency-free, C++ 11 based ThreadPool library.

dwThreadPool A simple, header-only, dependency-free, C++ 11 based ThreadPool library. Features C++ 11 Minimal Source Code Header-only No external depe

Dihara Wijetunga 27 Oct 28, 2022
Cpp-mempool - C++ header-only mempool library

cpp-mempool C++ header-only mempool library

Hardik Patel 13 Jun 21, 2022
Kokkos C++ Performance Portability Programming EcoSystem: The Programming Model - Parallel Execution and Memory Abstraction

Kokkos: Core Libraries Kokkos Core implements a programming model in C++ for writing performance portable applications targeting all major HPC platfor

Kokkos 1.2k Jan 5, 2023
EOSP ThreadPool is a header-only templated thread pool writtent in c++17.

EOSP Threadpool Description EOSP ThreadPool is a header-only templated thread pool writtent in c++17. It is designed to be easy to use while being abl

null 1 Apr 22, 2022
Fiber - A header only cross platform wrapper of fiber API.

Fiber Header only cross platform wrapper of fiber API A fiber is a particularly lightweight thread of execution. Which is useful for implementing coro

Tony Wang 41 Jul 31, 2022
Parallel-util - Simple header-only implementation of "parallel for" and "parallel map" for C++11

parallel-util A single-header implementation of parallel_for, parallel_map, and parallel_exec using C++11. This library is based on multi-threading on

Yuki Koyama 27 Jun 24, 2022
Parallel-hashmap - A family of header-only, very fast and memory-friendly hashmap and btree containers.

The Parallel Hashmap Overview This repository aims to provide a set of excellent hash map implementations, as well as a btree alternative to std::map

Gregory Popovitch 1.7k Jan 3, 2023
C++React: A reactive programming library for C++11.

C++React is reactive programming library for C++14. It enables the declarative definition of data dependencies between state and event flows. Based on

Sebastian 968 Dec 22, 2022
:copyright: Concurrent Programming Library (Coroutine) for C11

libconcurrent tiny asymmetric-coroutine library. Description asymmetric-coroutine bidirectional communication by yield_value/resume_value native conte

sharow 350 Sep 2, 2022
Cpp-taskflow - Modern C++ Parallel Task Programming Library

Cpp-Taskflow A fast C++ header-only library to help you quickly write parallel programs with complex task dependencies Why Cpp-Taskflow? Cpp-Taskflow

null 4 Mar 30, 2021
Single header asymmetric stackful cross-platform coroutine library in pure C.

minicoro Minicoro is single-file library for using asymmetric coroutines in C. The API is inspired by Lua coroutines but with C use in mind. The proje

Eduardo Bart 405 Dec 29, 2022
Coro - Single-header library facilities for C++2a Coroutines

coro This is a collection of single-header library facilities for C++2a Coroutines. coro/include/ co_future.h Provides co_future<T>, which is like std

Arthur O'Dwyer 66 Dec 6, 2022
A General-purpose Parallel and Heterogeneous Task Programming System

Taskflow Taskflow helps you quickly write parallel and heterogeneous tasks programs in modern C++ Why Taskflow? Taskflow is faster, more expressive, a

Taskflow 7.6k Dec 31, 2022