libcopp

C++ 中的跨平台 coroutine 程序库。「cross-platform coroutine library in c++」

libcopp

Cross-platform coroutine library in C++ .

image

image

Release
Code size
Repo size
CI build status
Coveralls coverage
Language grade: C/C++
Forks
Stars

CI Job Matrix


Target System Toolchain Note


Linux GCC Static linking

Linux GCC Dynamic linking

Linux GCC-latest

Linux GCC-latest No Exception

Linux GCC-latest Thread Unsafe

Linux GCC 4.8 Legacy

Linux Clang-latest With libc++

MinGW64 GCC Dynamic linking

Windows Visual Studio 2019 Static linking

Windows Visual Studio 2019 Dynamic linking

Windows Visual Studio 2017 Legacy,Static linking

macOS AppleClang With libc++

LICENSE

License under the MIT
LICENSE

Document

Documents can be found at https://libcopp.atframe.work , API
references canbe found at https://libcopp.atframe.work/doxygen/html/
.(Generated by sphinx and doxygen with
docs/sphinx and
docs/libcopp.doxyfile.in).

UPGRADE FROM 1.3.X-1.4.X to 2.X

  • Add using value_type = int; into T when using cotask::task<T>.
  • Rename stack_allocator_t to stack_allocator_type in T when
    using cotask::task<T>.
  • Rename coroutine_t to coroutine_type in T when using
    cotask::task<T>.
  • Rename libcopp::util::* to copp::util::.
  • We are not allowed to use
    libcopp::util::intrusive_ptr<cotask::impl::task_impl> now, please
    use cotask::task<T>::ptr_type instead.

UPGRADE FROM 1.2.X to 1.3.X-1.4.X

  • Rename cotask::task::await into cotask::task::await_task
  • Replace cotask::task<TCO_MACRO, TTASK_MACRO> with
    cotask::task<TCO_MACRO> , we don't allow to custom id allocator
    now.
  • Replace cotask::core::standard_int_id_allocator<uint64_t> with
    copp::util::uint64_id_allocator , we don't allow to custom id
    allocator now.
  • Require gcc 4.8+, MSVC 15+(Visual Studio 2017)>)
  • Require cmake 3.12.0 or upper

INSTALL

| libcopp use cmake to generate makefile and
switch build tools.

Prerequisites

Unix

  • [required] ar, as, ld
    (binutils) or
    llvm
  • [optional] if using
    gtest , pthread is required.

Windows

  • [required] masm (in MSVC)
  • [optional] if using
    gtest, pthread is required.

Install with vcpkg

Clone and setup [vcpkg](https://github.com/Microsoft/vcpkg) (See more detail on <https://github.com/Microsoft/vcpkg>)

:   ``` shell
    git clone https://github.com/Microsoft/vcpkg.git
    cd vcpkg
    PS> bootstrap-vcpkg.bootstrap
    Linux:~/$ ./bootstrap-vcpkg.sh
    ```
Install libcopp

:   ``` shell
    PS> .\vcpkg install libcopp [--triplet x64-windows-static/x64-windows/x64-windows-static-md and etc...]
    Linux:~/$ ./vcpkg install libcopp
    ```
  1. See using with cmake <usage-using with-cmake>{.interpreted-text
    role="ref"} for cmake below.

Custom Build

Clone and make a build directory

:   ``` shell
    git clone --single-branch --depth=1 -b master https://github.com/owent/libcopp.git 
    mkdir libcopp/build && cd libcopp/build
    ```
Run cmake command

:   ``` shell
    # cmake <libcopp dir> [options...]
    cmake .. -DPROJECT_ENABLE_UNITTEST=YES -DPROJECT_ENABLE_SAMPLE=YES
    ```
Make libcopp

:   ``` shell
    cmake --build . --config RelWithDebInfo # or make [options] when using Makefile
    ```
Run `test/sample/benchmark` *\[optional\]*

:   ``` shell
    # Run test => Required: PROJECT_ENABLE_UNITTEST=YES
    ctest -VV . -C RelWithDebInfo -L libcopp.unit_test
    # Run sample => Required: PROJECT_ENABLE_SAMPLE=YES
    ctest -VV . -C RelWithDebInfo -L libcopp.sample
    # Run benchmark => Required: PROJECT_ENABLE_SAMPLE=YES
    ctest -VV . -C RelWithDebInfo -L libcopp.benchmark
    ```
Install *\[optional\]*

:   ``` shell
    cmake --build . --config RelWithDebInfo --target install # or make install when using Makefile
    ```
  1. Then just include and link libcopp.*/libcotask.*, or see
    using with cmake <usage-using with-cmake>{.interpreted-text
    role="ref"} for cmake below.

CMake Options

Options can be cmake options. such as set compile toolchains, source
directory or options of libcopp that control build actions. libcopp
options are listed below:


Option Description


BUILD_SHARED_LIBS=YES|NO [default=NO] Build dynamic library.

LIBCOPP_ENABLE_SEGMENTED_STACKS=YES|NO [default=NO] Enable split stack supported
context.(it's only availabe in linux and gcc 4.7.0 or
upper)

LIBCOPP_ENABLE_VALGRIND=YES|NO [default=YES] Enable valgrind supported context.

PROJECT_ENABLE_UNITTEST=YES|NO [default=NO] Build unit test.

PROJECT_ENABLE_SAMPLE=YES|NO [default=NO] Build samples.

LIBCOPP_LOCK_DISABLE_THIS_MT=YES|NO [default=NO] Disable multi-thread support for
copp::this_coroutine and cotask::this_task.

LIBCOPP_DISABLE_ATOMIC_LOCK=YES|NO [default=NO] Disable multi-thread support.

LIBCOTASK_ENABLE=YES|NO [default=YES] Enable build libcotask.

LIBCOPP_FCONTEXT_USE_TSX=YES|NO [default=YES] Enable Intel Transactional
Synchronisation Extensions
(TSX)
.

LIBCOPP_MACRO_TLS_STACK_PROTECTOR=YES|NO [default=NO] Users need set
LIBCOPP_MACRO_TLS_STACK_PROTECTOR=ON when compiling
with -fstack-protector. Because it changes the
default context switching logic.

GTEST_ROOT=[path] set gtest library install prefix path

BOOST_ROOT=[path] set Boost.Test library install prefix path

USAGE

Using with cmake {#usage-using with-cmake}

  1. Using set(Libcopp_ROOT <where to find libcopp/INSTALL_PREFIX>)
  2. Just using
    find_package(Libcopp)
    to use libcopp module.
  3. Example:(we assume the target name is stored in
    ${CUSTOM_TARGET_NAME})
find_package(Libcopp CONFIG REQUIRED)
target_link_libraries(${CUSTOM_TARGET_NAME} libcopp::cotask)
# Or just using copp by target_link_libraries(${CUSTOM_TARGET_NAME} libcopp::copp)

If using MSVC and vcpkg, CRT must match the triplet of vcpkg, these
codes below may be helpful:

if (MSVC AND VCPKG_TOOLCHAIN)
    if(DEFINED ENV{VCPKG_DEFAULT_TRIPLET} AND NOT DEFINED VCPKG_TARGET_TRIPLET)
        set(VCPKG_TARGET_TRIPLET "$ENV{VCPKG_DEFAULT_TRIPLET}" CACHE STRING "")
    endif()
    if (VCPKG_TARGET_TRIPLET MATCHES "^.*windows-static$")
        set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>" CACHE STRING "")
    else ()
        set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL" CACHE STRING "")
    endif ()
endif ()

See more detail on
https://github.com/Microsoft/vcpkg/tree/master/ports/libcopp .

Directly use headers and libraries

Just include headers and linking library file of your platform to use
libcopp.

LIBCOPP_PREFIX=<WHERE TO INSTALL libcopp>

# Example command for build sample with gcc 4.9 or upper on Linux
for source in sample_readme_*.cpp; do
    g++ -std=c++14 -O2 -g -ggdb -Wall -Werror -fPIC -rdynamic -fdiagnostics-color=auto -Wno-unused-local-typedefs \
        -I$LIBCOPP_PREFIX/include -L$LIBCOPP_PREFIX/lib64 -lcopp -lcotask $source -o $source.exe;
done

# Example command for build sample with clang 3.9 or upper and libc++ on Linux
for source in sample_readme_*.cpp; do
    clang++ -std=c++17 -stdlib=libc++ -O2 -g -ggdb -Wall -Werror -fPIC -rdynamic        \
        -I$LIBCOPP_PREFIX/include -L$LIBCOPP_PREFIX/lib64 -lcopp -lcotask -lc++ -lc++abi  \
        $source -o $source.exe;
done

# AppleClang on macOS just like those scripts upper.
# If you are using MinGW on Windows, it's better to add -static-libstdc++ -static-libgcc to 
#     use static linking and other scripts are just like those on Linux.
# Example command for build sample with MSVC 1914 or upper on Windows & powershell(Debug Mode /MDd)
foreach ($source in Get-ChildItem -File -Name .\sample_readme_*.cpp) {
    cl /nologo /MP /W4 /wd"4100" /wd"4125" /EHsc /std:c++17 /Zc:__cplusplus /O2 /MDd /I$LIBCOPP_PREFIX/include $LIBCOPP_PREFIX/lib64/copp.lib $LIBCOPP_PREFIX/lib64/cotask.lib $source
}

Get Start & Example

There serveral samples to use copp::coroutine_context
copp::coroutine_context_fiber and cotask::task :

  1. Using coroutine context
  2. Using coroutine task
  3. Using coroutine task manager
  4. Using stack pool
  5. Using task::then or task::await_task
  6. Using copp::callable_promise of c++20 coroutine
  7. Using copp::generator_future for c++20 coroutine
  8. Custom error (timeout for example) when using c++20 coroutine
  9. Let c++20 coroutine work with cotask::task
  10. Using Windows fiber and SetUnhandledExceptionFilter on Windows
    with cotask::task

All sample codes can be found on
EXAMPLES <examples_doc_anchor>{.interpreted-text role="ref"} and
sample .

NOTICE

Split stack support: if in Linux and user gcc 4.7.0 or upper, add
-DLIBCOPP_ENABLE_SEGMENTED_STACKS=YES to use split stack supported
context.

It's recommanded to use stack pool instead of gcc splited stack.

BENCHMARK

Please see CI output for latest benchmark report. Click to visit Github
Actions
.

FAQ

Q: How to enable c++20 coroutine

| ANS: Add /std:c++latest /await for MSVC 1932 and below or
-std=c++20 -fcoroutines-ts -stdlib=libc++ for clang 13 and below or
-std=c++20 -fcoroutines for gcc 10.

If you can just use -std=c++20 -stdlib=libc++ clang 14 or above,
-astd=c++20 for gcc 11 or above, and /std:c++latest for MSVC 1932 or
above.

Q: Will libcopp handle exception?

| ANS: When using c++11 or above, libcopp will catch all unhandled
exception and rethrow it after coroutine resumed.

Q: Why SetUnhandledExceptionFilter can not catch the unhandled
exception in a coroutine?

| ANS: SetUnhandledExceptionFilter only works with Windows Fiber,
please see
sample/sample_readme_11.cpp
for details.

FEEDBACK

If you has any question, please create a issue and provide the
information of your environments. For example:

  • OS: Windows 10 Pro 19041 (This can be see after running
    ``msinfo32``)
    / Manjaro(Arch) Linux Linux 5.4.39-1-MANJARO
  • Compiler: Visual Studio 2019 C++ 16.5.5 with VS 2019 C++ v14.25
    or MSVC 1925/ gcc 9.3.0
  • CMake Commands:
    cmake .. -G "Visual Studio 16 2019" -A x64 -DLIBCOPP_FCONTEXT_USE_TSX=ON -DPROJECT_ENABLE_UNITTEST=ON -DPROJECT_ENABLE_SAMPLE=ON-DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=%cd%/install-prefix
    /
    cmake .. -G Ninja -DLIBCOPP_FCONTEXT_USE_TSX=ON -DPROJECT_ENABLE_UNITTEST=ON -DPROJECT_ENABLE_SAMPLE=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/opt/libcopp
  • Compile Commands: cmake --build . -j
  • Related Environment Variables: Please provide all the
    environment variables which will change the cmake toolchain, CC
    CXXAR and etc.

CONSTRIBUTORS

THANKS TO

Overview

Name With Ownerowent/libcopp
Primary LanguageC++
Program languageCMake (Language Count: 7)
Platform
License:MIT License
Release Count26
Last Release Namev2.2.0 (Posted on 2023-04-13 19:17:34)
First Release Namev0.1.0 (Posted on )
Created At2013-12-10 13:45:56
Pushed At2023-10-25 14:33:04
Last Commit At2020-12-26 17:10:54
Stargazers Count804
Watchers Count40
Fork Count104
Commits Count672
Has Issues Enabled
Issues Count23
Issue Open Count0
Pull Requests Count28
Pull Requests Open Count0
Pull Requests Close Count3
Has Wiki Enabled
Is Archived
Is Fork
Is Locked
Is Mirror
Is Private
To the top