From 5db25c41739d3fcf80efb39b5a9e98bc623ddffc Mon Sep 17 00:00:00 2001 From: Vladislav Shpilevoy Date: Wed, 29 Jan 2025 23:21:55 +0100 Subject: [PATCH] readme: use relative GitHub links GitHub allows to specify clickable links to local files in Markdown. Lets use this feature to simplify reading on GitHub. Thanks to @Totktonada for the idea. --- README.md | 10 ++++++---- src/mg/aio/README.md | 4 ++-- src/mg/sch/README.md | 6 +++--- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 7664e968..c25cbced 100644 --- a/README.md +++ b/README.md @@ -48,11 +48,13 @@ t->SetCallback([](Task *self) -> mg::box::Coro { sched.Post(t); ``` -See more in `src/mg/sch/README.md`. +See more in [src/mg/sch/README.md](/src/mg/sch/README.md). ## `IOCore` -**IOCore** is a multi-threaded event-loop for asynchronous code execution and network IO. It is like `TaskScheduler`, the internal architecture and the API are very similar, but `IOCore`'s main use case is work with sockets and efficient IO. You can think of it as if each of your sockets (server, accepted sockets, client sockets) is like a very lightweight coroutine. See more in `src/mg/aio/README.md`. +**IOCore** is a multi-threaded event-loop for asynchronous code execution and network IO. It is like `TaskScheduler`, the internal architecture and the API are very similar, but `IOCore`'s main use case is work with sockets and efficient IO. You can think of it as if each of your sockets (server, accepted sockets, client sockets) is like a very lightweight coroutine. + +See more in [src/mg/aio/README.md](/src/mg/aio/README.md). A simple example: ```C++ @@ -198,5 +200,5 @@ If none of the proposed interception endpoints are needed, you can simply link w See more details here: -- `src/mg/sch/README.md` -- `src/mg/aio/README.md` +- [src/mg/sch/README.md](/src/mg/sch/README.md) +- [src/mg/aio/README.md](/src/mg/aio/README.md) diff --git a/src/mg/aio/README.md b/src/mg/aio/README.md index e25c6027..cfc1c55c 100644 --- a/src/mg/aio/README.md +++ b/src/mg/aio/README.md @@ -57,9 +57,9 @@ private: }; ``` -`IOCore` (`src/mg/aio/IOCore.h`) is the event-loop itself. `IOTask` (`src/mg/aio/IOTask.h`) is a task context which a socket can be attached to, or any other data of your choice. With a socket attached `IOTask` can do asynchronous IO. In addition to that it also has the task features - wakeup and deadlines, just like `Task` in `TaskScheduler`. +`IOCore` ([src/mg/aio/IOCore.h](/src/mg/aio/IOCore.h)) is the event-loop itself. `IOTask` ([src/mg/aio/IOTask.h](/src/mg/aio/IOTask.h)) is a task context which a socket can be attached to, or any other data of your choice. With a socket attached `IOTask` can do asynchronous IO. In addition to that it also has the task features - wakeup and deadlines, just like `Task` in `TaskScheduler`. -For convenience some of the most popular socket types are already implemented on top of `IOTask`, such as `TCPSocket` (`src/mg/aio/TCPSocket.h`) for pure TCP interaction and `TCPServer` (`src/mg/aio/TCPServer.h`) for accepting new clients. +For convenience some of the most popular socket types are already implemented on top of `IOTask`, such as `TCPSocket` ([src/mg/aio/TCPSocket.h](/src/mg/aio/TCPSocket.h)) for pure TCP interaction and `TCPServer` ([src/mg/aio/TCPServer.h](/src/mg/aio/TCPServer.h)) for accepting new clients. For building more specific sockets you can use those as a basis, or directly inherit `TCPSocketIFace`. diff --git a/src/mg/sch/README.md b/src/mg/sch/README.md index c7b3996c..17d3fc21 100644 --- a/src/mg/sch/README.md +++ b/src/mg/sch/README.md @@ -323,7 +323,7 @@ The scheduler is not a single monolithic algorithm. It is fused from several sma ### Multi-Producer-Single-Consumer Queue -The scheduler receives tasks from the external code via a front queue. It is an unbounded lock-free MPSC queue. See `src/mg/box/MultiProducerQueueIntrusive.h`. +The scheduler receives tasks from the external code via a front queue. It is an unbounded lock-free MPSC queue. See [src/mg/box/MultiProducerQueueIntrusive.h](/src/mg/box/MultiProducerQueueIntrusive.h). Push is an atomic compare-exchange which in case of simultaneous access by multiple threads is retried. No spinlocks, nor any mutexes. @@ -331,7 +331,7 @@ Pop is only able to take all the tasks at once and the order is reversed. That i ### Multi-Consumer-Single-Producer Queue -This is a backend queue of the scheduler. From here the worker threads pick up the tasks ready for execution. It is an unbounded semi-lock-free MCSP queue. See `src/mg/box/MultiConsumerQueue.h`. +This is a backend queue of the scheduler. From here the worker threads pick up the tasks ready for execution. It is an unbounded semi-lock-free MCSP queue. See [src/mg/box/MultiConsumerQueue.h](/src/mg/box/MultiConsumerQueue.h). There is no a simple well known algorithm for having multiple consumers which would be at the same time wait-free; lock-free; unbounded; and with ability to pop items one by one. Mostly that is because of the ABA problem of concurrent algorithms. Working them around usually is quite untrivial and can cost notable fraction of performance. @@ -380,7 +380,7 @@ Linux WSL 1: ### Signal -Signal is a thread synchronization type, similar to mutex and condition variable. It allows to send an event from one thread to another in a blocking way, but it has a few most common cases optimized to be lock-free. See `src/mg/box/Signal.h`. +Signal is a thread synchronization type, similar to mutex and condition variable. It allows to send an event from one thread to another in a blocking way, but it has a few most common cases optimized to be lock-free. See [src/mg/box/Signal.h](/src/mg/box/Signal.h). The scheduler uses it to - Notify the worker threads about new ready-to-do tasks coming;