Skip to content

A simple stackful asymmetric scheduling coroutine library for modern C++ on Linux.

License

Notifications You must be signed in to change notification settings

cucurryx/ecoroutine

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ecoroutine

A simple stackful asymmetric scheduling coroutine library for modern C++.

  • schedule algorithm: asymmetric coroutine sheduling, same as libgo
  • coroutine stack: virtual memory stack

How to use?

build

cmake .
make example && make benchmark

create a coroutine

ecoroutine::CoroutineFunc func = [i](){};
coroutine_t c = ecoroutine::create(func);

Notice: this create is different from the pthread_create, since the coroutine will not begin to work immediatly. You need to call ecoroutine::start.

run a coroutine

If a coroutie has been created but not running yet, you need run. If a coroutine has called yield, you need run to make it running again.

ecoroutine::run(c);

yield a coroutine

ecoroutine::yield();

yield will yield the current running coroutine. If you try to yield the main coroutine, it'll report an error. Because coroutine is non-preemptive, the only way to give up control of CPU is yield. And the current coroutine's state will change to HangUp, and the scheduler will begin to work.

How's the performance?

Comparing to C++11 std::thread, ecoroutine doesn't need to do context switch in kernel mode. So it's quietly faster than std::thread.

I create and destroy thread/coroutine for 10,000,000 times to show the difference of their performance.

./pics/bench.png

benchmark code:

constexpr uint32_t loop_times = 500 * 1000;

uint64_t coroutine_test() {
    ecoroutine::CoroutineFunc func = [](){};

    clock_t start = clock();
    for (int i = 0; i < loop_times; ++i) {
        ecoroutine::coroutine_t coroutine1 = ecoroutine::create(func);
        ecoroutine::coroutine_t coroutine2 = ecoroutine::create(func);
        ecoroutine::run(coroutine1);
        ecoroutine::run(coroutine2);
    }
    clock_t end = clock();

    return end - start;
}

uint64_t thread_test() {
    auto func = [](){};
    clock_t start = clock();
    for (int i = 0; i < loop_times; ++i) {
        std::thread thread1(func);
        std::thread thread2(func);
        thread1.join();
        thread2.join();
    }
    clock_t end = clock();

    return end - start;
}

int main(int argc, char* argv[]) {
    const int kMicrosecondsPerSecond = 1000 * 1000;
    printf("coroutine: %d times %f s\n", loop_times * 2,
           static_cast<double>(coroutine_test()) / kMicrosecondsPerSecond);
    printf("thread: %d times %f s\n", loop_times * 2,
           static_cast<double>(thread_test()) / kMicrosecondsPerSecond);
    return 0;
}

future

  • maybe a channel for data transfer
  • maybe hook for networking I/O

About

A simple stackful asymmetric scheduling coroutine library for modern C++ on Linux.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages