Skip to content

Commit e92a814

Browse files
committed
#feat: Update to v1.2
1 parent b06bc9d commit e92a814

38 files changed

Lines changed: 1088 additions & 105 deletions

.github/workflows/ci-ubuntu.yml

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# This starter workflow is for a CMake project running on a single platform. There is a different starter workflow if you need cross-platform coverage.
2+
# See: https://github.com/actions/starter-workflows/blob/main/ci/cmake-multi-platform.yml
3+
name: CMake on ubuntu
4+
5+
on:
6+
push:
7+
branches: [ "master" ]
8+
pull_request:
9+
branches: [ "master" ]
10+
11+
env:
12+
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
13+
BUILD_TYPE: Release
14+
15+
jobs:
16+
build:
17+
# The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac.
18+
# You can convert this to a matrix build if you need cross-platform coverage.
19+
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
20+
runs-on: ubuntu-latest
21+
22+
steps:
23+
- uses: actions/checkout@v4
24+
25+
- name: Setup Python
26+
uses: actions/setup-python@v5.6.0
27+
with:
28+
# Version range or exact version of Python or PyPy to use, using SemVer's version range syntax. Reads from .python-version if unset.
29+
python-version: 3.12.10
30+
# File containing the Python version to use. Example: .python-version
31+
# python-version-file: # optional
32+
# Used to specify a package manager for caching in the default directory. Supported values: pip, pipenv, poetry.
33+
# cache: # optional
34+
# The target architecture (x86, x64, arm64) of the Python or PyPy interpreter.
35+
architecture: x64
36+
# Set this option if you want the action to check for the latest available version that satisfies the version spec.
37+
# check-latest: # optional
38+
# The token used to authenticate when fetching Python distributions from https://github.com/actions/python-versions. When running this action on github.com, the default value is sufficient. When running on GHES, you can pass a personal access token for github.com if you are experiencing rate limiting.
39+
# token: # optional, default is ${{ github.server_url == 'https://github.com' && github.token || '' }}
40+
# Used to specify the path to dependency files. Supports wildcards or a list of file names for caching multiple dependencies.
41+
# cache-dependency-path: # optional
42+
# Set this option if you want the action to update environment variables.
43+
# update-environment: # optional, default is true
44+
# When 'true', a version range passed to 'python-version' input will match prerelease versions if no GA versions are found. Only 'x.y' version range is supported for CPython.
45+
# allow-prereleases: # optional
46+
# When 'true', use the freethreaded version of Python.
47+
# freethreaded: # optional
48+
49+
- name: Python deps install
50+
run: pip install pyyaml
51+
52+
- name: Submodule init
53+
uses: actions/checkout@v4
54+
with:
55+
submodules: true
56+
57+
- name: Install Liburing
58+
run: |
59+
mkdir temp
60+
cd temp
61+
git clone https://github.com/axboe/liburing.git
62+
cd liburing
63+
./configure --cc=gcc --cxx=g++
64+
make -j$(nproc)
65+
make liburing.pc
66+
sudo make install
67+
68+
- name: Configure CMake
69+
# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
70+
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
71+
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
72+
73+
- name: Build
74+
# Build your program with the given configuration
75+
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
76+
77+
- name: Test
78+
working-directory: ${{github.workspace}}/build
79+
# Execute tests defined by the CMake configuration.
80+
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
81+
run: |
82+
cp ${{github.workspace}}/scripts/CITests.py ${{github.workspace}}/build/CITests.py
83+
cp ${{github.workspace}}/scripts/CITests.yml ${{github.workspace}}/build/CITests.yml
84+
python CITests.py
85+

README.MD

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44

55
-----------------
66

7-
# tinyCoroLab Course
7+
# 🚀tinyCoroLab Course
88

99
[![C++20](https://img.shields.io/badge/dialect-C%2B%2B20-blue)](https://en.cppreference.com/w/cpp/20)[![MIT license](https://img.shields.io/github/license/max0x7ba/atomic_queue)](https://github.com/sakurs2/tinyCoro/blob/master/LICENSE)![platform Linux x86_64](https://img.shields.io/badge/platform-Linux%20x86_64--bit-yellow)
10-
![Version Badge](https://img.shields.io/badge/version-v1%2E1-red)
10+
![Version Badge](https://img.shields.io/badge/version-v1%2E2-red)
1111
<!-- support below -->
1212
<!-- [![Build Status](link/actions/workflows/cmake.yml/badge.svg)](link/actions/workflows/cmake.yml) -->
1313
<!-- [![CI](https://github.com/jbaldwin/libcoro/actions/workflows/ci-coverage.yml/badge.svg)](https://github.com/jbaldwin/libcoro/actions/workflows/ci-coverage.yml)
@@ -197,6 +197,12 @@ $ tree -d -A -I third_party -I build -I .vscode -I resource -I temp
197197

198198
这四个文件夹存储了[tinyCoroLab](https://github.com/sakurs2/tinyCoroLab)用于执行功能测试、内存安全测试、性能测试和实验辅助脚本的文件,具体使用方法后续会详细介绍。
199199

200+
### CI流水线
201+
202+
tinyCoroLab默认配置了一条基于ubuntu系统的CI流水线,主要执行编译构建以及各项测试的流程,具体文件可见[.github/workflows/ci-ubuntu.yml](https://github.com/sakurs2/tinyCoroLab/tree/master/.github/workflows/ci-ubuntu.yml)
203+
204+
该CI流水线强制执行编译构建过程,对于各项测试根据用户配置文件选择性执行,用户可编辑[scripts/CITests.yml](https://github.com/sakurs2/tinyCoroLab/tree/master/scripts/CITests.yml)来控制某项测试是否被执行。
205+
200206
### tinyCoroLab实验小技巧
201207

202208
在了解[tinyCoroLab](https://github.com/sakurs2/tinyCoroLab)各个模块后,本节将会告诉大家如何正确的使用本实验精心构建并提供给实验者的各个技巧。注意本节提到的所有指令必须在构建目录下运行。

benchmark/tinycoro_model/tinycoro_128_bench.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ using namespace coro;
99
task<> session(int fd)
1010
{
1111
char buf[BUFFLEN] = {0};
12-
auto conn = net::tcp_connector(fd);
12+
auto conn = io::net::tcp::tcp_connector(fd);
1313
int ret = 0;
1414

1515
while ((ret = co_await conn.read(buf, BUFFLEN)) > 0)
@@ -26,7 +26,7 @@ task<> session(int fd)
2626

2727
task<> server(int port)
2828
{
29-
auto server = net::tcp_server(port);
29+
auto server = io::net::tcp::tcp_server(port);
3030
log::info("server start in {}", port);
3131
int client_fd;
3232
while ((client_fd = co_await server.accept()) > 0)

benchmark/tinycoro_model/tinycoro_16k_bench.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ using namespace coro;
77
task<> session(int fd)
88
{
99
char buf[BUFFLEN] = {0};
10-
auto conn = net::tcp_connector(fd);
10+
auto conn = io::net::tcp::tcp_connector(fd);
1111
int ret = 0;
1212

1313
while ((ret = co_await conn.read(buf, BUFFLEN)) > 0)
@@ -25,7 +25,7 @@ task<> session(int fd)
2525

2626
task<> server(int port)
2727
{
28-
auto server = net::tcp_server(port);
28+
auto server = io::net::tcp::tcp_server(port);
2929
log::info("server start in {}", port);
3030
int client_fd;
3131
while ((client_fd = co_await server.accept()) > 0)

benchmark/tinycoro_model/tinycoro_1k_bench.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ using namespace coro;
77
task<> session(int fd)
88
{
99
char buf[BUFFLEN] = {0};
10-
auto conn = net::tcp_connector(fd);
10+
auto conn = io::net::tcp::tcp_connector(fd);
1111
int ret = 0;
1212

1313
while ((ret = co_await conn.read(buf, BUFFLEN)) > 0)
@@ -25,7 +25,7 @@ task<> session(int fd)
2525

2626
task<> server(int port)
2727
{
28-
auto server = net::tcp_server(port);
28+
auto server = io::net::tcp::tcp_server(port);
2929
log::info("server start in {}", port);
3030
int client_fd;
3131
while ((client_fd = co_await server.accept()) > 0)

config/config.h.in

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
#include "stddef.h"
2222
#include "stdint.h"
23+
#include "time.h"
24+
#include <limits>
2325

2426
#include "coro/detail/types.hpp"
2527

@@ -53,6 +55,13 @@ constexpr int64_t kFlushDura = 3; // seconds
5355
// use alignas(config::kCacheLineSize) to reduce cache invalidation
5456
constexpr size_t kCacheLineSize = 64;
5557

58+
// ====================== memory allocator configuration ====================
59+
// only ENABLE_MEMORY_ALLOC is defined, the memory allocator strategy will be enabled
60+
#define ENABLE_MEMORY_ALLOC
61+
62+
// memory allocator is used to allocate memory for coroutine
63+
constexpr coro::detail::memory_allocator kMemoryAllocator = coro::detail::memory_allocator::std_allocator;
64+
5665
// ========================== uring configuration ===========================
5766
// io_uring queue length
5867
constexpr unsigned int kEntryLength = 10240;
@@ -86,6 +95,11 @@ constexpr size_t kQueCap = 16384;
8695
// scheduler dispacher strategy
8796
constexpr coro::detail::dispatch_strategy kDispatchStrategy = coro::detail::dispatch_strategy::round_robin;
8897

98+
// If one thread submit task to another thread or itself which owns a full task queue,
99+
// the submit func will be blocked, so execuate this task directly instead of submitting task,
100+
// but this will cause recursive call, so use this parameter to constrain the recursive depth
101+
constexpr size_t kMaxRecursiveDepth = 4096;
102+
89103
/**
90104
* @warning kLongRunMode is deprecated
91105
*
@@ -104,10 +118,40 @@ constexpr coro::detail::dispatch_strategy kDispatchStrategy = coro::detail::disp
104118
*/
105119
inline bool kLongRunMode = true;
106120

107-
// =========================== net configuration ============================
121+
// =========================== tcp configuration ============================
108122
constexpr int kDefaultPort = 8000;
109123
constexpr int kBacklog = 5;
110124

125+
// ========================== http configuration ============================
126+
127+
// server config
128+
// constexpr size_t kHttpRedirectMaxCount = 20;
129+
// constexpr size_t kHttpKeepAliveMaxCount = 100;
130+
// constexpr time_t kHttpKeepAliveTimeoutSecond = 5;
131+
// constexpr time_t kHttpServerReadTimeoutSecond = 5;
132+
// constexpr time_t kHttpServerReadTimeoutUSecond = 0;
133+
// constexpr time_t kHttpServerWriteTimeoutSecond = 5;
134+
// constexpr time_t kHttpServerWriteTimeoutUSecond = 0;
135+
// constexpr time_t kHttpIdleIntervalSecond = 0;
136+
// constexpr time_t kHttpIdleIntervalUSecond = 0;
137+
// constexpr time_t kHttpPayloadMaxLength = ((std::numeric_limits<size_t>::max)());
138+
139+
// // client config
140+
// constexpr time_t kHttpConnectionTimeoutSecond = 300;
141+
// constexpr time_t kHttpConnectionTimeoutUSecond = 0;
142+
// constexpr time_t kHttpClientReadTimeoutSecond = 300;
143+
// constexpr time_t kHttpClientReadTimeoutUSecond = 0;
144+
// constexpr time_t kHttpClientWriteTimeoutSecond = 5;
145+
// constexpr time_t kHttpClientWriteTimeoutUSecond = 0;
146+
// constexpr time_t kHttpClientMaxTimeoutMSecond = 0;
147+
148+
// constexpr size_t kHttpHeaderMaxLength = 8192;
149+
// constexpr size_t kHttpRequestUriMaxLength = 8192;
150+
// constexpr bool kHttpTcpNodeLay = false;
151+
// constexpr bool kHttpIpv6Only = false;
152+
// constexpr size_t kHttpRangeMaxCount = 1024;
153+
// constexpr int kHttpListenBacklog = 5;
154+
111155
// ========================== test configuration ============================
112156
/**
113157
* @brief kMaxTestTaskNum represents the maximum value in the test case

examples/parallel_calc.cpp

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,39 @@
1-
#include <vector>
2-
31
#include "coro/coro.hpp"
42

53
using namespace coro;
64

7-
#define TASK_NUM 5
8-
9-
std::vector<int> vec{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
5+
task<int> square(int i)
6+
{
7+
co_return i* i;
8+
}
109

11-
task<> calc(int id, int lef, int rig, std::vector<int>& v)
10+
task<> parallel_compute()
1211
{
13-
int sum = 0;
14-
for (int i = lef; i < rig; i++)
12+
std::vector<task<int>> vec;
13+
for (int i = 1; i <= 5; i++)
1514
{
16-
sum += v[i];
15+
vec.push_back(square(i));
1716
}
18-
log::info("task {} calc result: {}", id, sum);
19-
co_return;
17+
auto answer = co_await parallel::parallel_func(
18+
vec,
19+
parallel::make_parallel_reduce_func(
20+
[](std::vector<int>& vec)
21+
{
22+
int sum = 0;
23+
for (auto it : vec)
24+
{
25+
sum += it;
26+
}
27+
return sum;
28+
}));
29+
log::info("final answer: {}", answer);
2030
}
2131

2232
int main(int argc, char const* argv[])
2333
{
2434
/* code */
2535
scheduler::init();
26-
27-
for (int i = 0; i < TASK_NUM; i++)
28-
{
29-
submit_to_scheduler(calc(i, i * 3, (i + 1) * 3, vec));
30-
}
31-
36+
submit_to_scheduler(parallel_compute());
3237
scheduler::loop();
3338
return 0;
3439
}

examples/stdin_client.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,34 @@ task<> echo(int sockfd)
88
{
99
char buf[BUFFLEN] = {0};
1010
int ret = 0;
11-
auto conn = net::tcp_connector(sockfd);
11+
auto conn = io::net::tcp::tcp_connector(sockfd);
1212

1313
while (true)
1414
{
15-
ret = co_await net::stdin_awaiter(buf, BUFFLEN, 0);
15+
ret = co_await io::stdin_awaiter(buf, BUFFLEN, 0);
1616
log::info("receive data from stdin: {}", buf);
1717
ret = co_await conn.write(buf, ret);
1818
}
1919
}
2020

2121
task<> client(const char* addr, int port)
2222
{
23-
auto client = net::tcp_client(addr, port);
23+
auto client = io::net::tcp::tcp_client(addr, port);
2424
int ret = 0;
2525
int sockfd = 0;
2626
sockfd = co_await client.connect();
2727
assert(sockfd > 0 && "connect error");
2828

29+
if (sockfd <= 0)
30+
{
31+
log::error("connect error");
32+
co_return;
33+
}
34+
2935
submit_to_scheduler(echo(sockfd));
3036

3137
char buf[BUFFLEN] = {0};
32-
auto conn = net::tcp_connector(sockfd);
38+
auto conn = io::net::tcp::tcp_connector(sockfd);
3339
while ((ret = co_await conn.read(buf, BUFFLEN)) > 0)
3440
{
3541
log::info("receive data from net: {}", buf);

examples/tcp_echo_client.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@ using namespace coro;
77
task<> client(const char* addr, int port)
88
{
99
log::info("client ready to start");
10-
auto client = net::tcp_client(addr, port);
10+
auto client = io::net::tcp::tcp_client(addr, port);
1111
int ret = 0;
1212
int sockfd = 0;
1313
sockfd = co_await client.connect();
1414
assert(sockfd > 0 && "connect error");
1515
log::info("connect success");
1616

1717
char buf[BUFFLEN] = {0};
18-
auto conn = net::tcp_connector(sockfd);
18+
auto conn = io::net::tcp::tcp_connector(sockfd);
1919
while ((ret = co_await conn.read(buf, BUFFLEN)) > 0)
2020
{
2121
log::info("client {} receive data: {}", sockfd, buf);

examples/tcp_echo_server.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ using namespace coro;
77
task<> session(int fd)
88
{
99
char buf[BUFFLEN] = {0};
10-
auto conn = net::tcp_connector(fd);
10+
auto conn = io::net::tcp::tcp_connector(fd);
1111
int ret = 0;
1212
while ((ret = co_await conn.read(buf, BUFFLEN)) > 0)
1313
{
@@ -23,7 +23,7 @@ task<> session(int fd)
2323
task<> server(int port)
2424
{
2525
log::info("server start in {}", port);
26-
auto server = net::tcp_server(port);
26+
auto server = io::net::tcp::tcp_server(port);
2727
int client_fd;
2828
while ((client_fd = co_await server.accept()) > 0)
2929
{

0 commit comments

Comments
 (0)