1libconcurrent
2=============
3[![zlib License](http://img.shields.io/badge/license-zlib-orange.svg?style=flat-square)](https://github.com/sharow/libconcurrent/blob/master/LICENSE)
4
5
6tiny asymmetric-coroutine library.
7
8## Description
9+ asymmetric-coroutine
10+ bidirectional communication by `yield_value`/`resume_value`
11+ native context switch
12+ C11
13
14## Supported Platforms
15|              | x86_64              | i686                     | ARM(v6/v7)               | AArch64            | (contributor)    |
16|--------------|---------------------|--------------------------|--------------------------|--------------------|------------------|
17| Linux        | :heavy_check_mark:  | :heavy_check_mark:       | :heavy_check_mark:       | :heavy_check_mark: |                  |
18| FreeBSD      | :heavy_check_mark:  | :heavy_check_mark:       | :question:               | :question:         |[@t6](https://github.com/t6)|
19| OSX          | :heavy_check_mark:  | :heavy_multiplication_x: | :heavy_multiplication_x: | :heavy_check_mark: |[@kpamnany](https://github.com/kpamnany) |
20| (contributor)|                     |                          |                          |[@mitghi](https://github.com/mitghi)| |
21
22## Code Example
23
24```c
25#include <stdio.h>
26#include <stdlib.h>
27#include <stdint.h>
28#include <stdnoreturn.h>
29
30#include <concurrent/concurrent.h>
31#include <concurrent/shortname.h>
32
33#define STACK_SIZE (1024 * 2)
34
35
36noreturn void accumulator(struct concurrent_ctx *ctx)
37{
38    int *v = ctx_get_resume_value(ctx);
39    int total = *v;
40    for (;;) {
41        v = yield_value(ctx, &total); // send total / receive next value
42        total += *v;
43    }
44}
45
46int main(void)
47{
48    struct concurrent_ctx *ctx;
49    uint8_t stack[STACK_SIZE];
50    uint8_t ctx_alloc[ctx_sizeof()];
51    concurrent_init();
52    ctx = (struct concurrent_ctx *)ctx_alloc;
53    ctx_construct(ctx, stack, STACK_SIZE, accumulator, NULL);
54    for (int i = 1; i <= 10; i++) {
55        int *total = resume_value(ctx, &i); // send value / receive total
56        printf("total = %d\n", *total);
57
58    }
59    ctx_destruct(ctx);
60    concurrent_fin();
61    return EXIT_SUCCESS;
62}
63
64/*
65$ gcc -o sample sample.c -lconcurrent.a
66$ ./sample
67total = 1
68total = 3
69total = 6
70total = 10
71total = 15
72total = 21
73total = 28
74total = 36
75total = 45
76total = 55
77*/
78```
79
80## Requirements for build
81- for x86_64/i686: [nasm](http://www.nasm.us/)
82
83
84## Installation
85```
86$ git clone https://github.com/sharow/libconcurrent.git libconcurrent
87$ cd libconcurrent
88$ make
89$ sudo make install
90
91```
92
93#### for FreeBSD
94Available in ports collection as [devel/libconcurrent](http://portsmon.freebsd.org/portoverview.py?category=devel&portname=libconcurrent)
95
96
97#### for OSX
98- install latest [nasm](http://www.nasm.us/) from [brew](http://brew.sh)
99
100```
101$ brew install nasm
102```
103
104## Tests
105```
106$ make test
107
108```
109
110## Benchmark
111
112[examples/many_context1.c](https://github.com/sharow/libconcurrent/blob/master/examples/many_context1.c):
113
114```
115-- output: (Xeon E3 2.5Ghz)
1163000000 context switch in 373.5 ms
117one context switch in 125 ns
1188031333 resume/yield pair per second
119
120
121-- output: (RaspberryPi2 ARMv7 900MHz)
1223000000 context switch in 2861.8 ms
123one context switch in 954 ns
1241048287 resume/yield pair per second
125```
126
127
128## VS.
129+ Portable Coroutine Library (PCL): http://xmailserver.org/libpcl.html
130+ libtask: https://code.google.com/p/libtask/
131+ libconcurrency: http://code.google.com/p/libconcurrency/
132+ libcoro: http://software.schmorp.de/pkg/libcoro.html
133+ libcoroutine: https://github.com/stevedekorte/coroutine
134+ coro: http://www.goron.de/~froese/coro/
135+ libfiber: http://www.rkeene.org/projects/info/wiki/22
136+ mill: https://github.com/sustrik/mill
137+ fcontext: https://github.com/reginaldl/fcontext
138+ libwire: https://github.com/baruch/libwire
139+ coroutine(A asymmetric coroutine library for C): https://github.com/cloudwu/coroutine
140+ coroutine(a asymmetric coroutine (lua like) with fixed-size stack): https://github.com/xphh/coroutine
141+ coroutine(coroutine library with pthread-like interface in pure C): https://github.com/Marcus366/coroutine
142+ coroutines(A lightweight coroutine library written in C and assembler): https://github.com/xya/coroutines
143+ micro: https://github.com/mikewei/micoro
144