Closed hayyp closed 3 years ago
I like the idea of including an example. Once upon a time libco actually came with an example that was also a benchmark and a smoke-test — perhaps I should dig that code out and add it to the repo. How does that sound?
The language in the description feels a bit "casual", for the lack of a better term. It needs to be precise enough for experts, in addition to being understandable for the beginners.
How does the following look? @ahhzee Is this still understandable to you?
typedef void* cothread_t;
Handle to cothread.
Handle must be of type void*
.
A value of null
(0) indicates an uninitialized or invalid handle, whereas a non-zero
value indicates a valid handle. A valid handle is backed by execution state to which the
execution can be co_switch()
ed to.
cothread_t co_active();
Return a valid cothread_t.
Note that the handle is valid even if the function is called from a non-cothread
context. To achieve this, we save the execution state in an internal buffer,
instead of using the user-provided memory. Since this handle is valid, it can
be used to co_switch
to this context from another cothread. In multi-threaded
applications, make sure to not switch non-cothread context across CPU cores,
to prevent any possible conflicts with the OS scheduler.
I like the idea of including an example. Once upon a time libco actually came with an example that was also a benchmark and a smoke-test — perhaps I should dig that code out and add it to the repo. How does that sound?
There should probably be two code samples -- one for beginners just trying to get something to compile and run, and another that can serve as both an advanced reference as well as a stress test/benchmark.
an example that was also a benchmark and a smoke-test
I think that's cool, you can never have too many examples, but I think a simple example can help clarify things and help people get started.
To achieve this, we save the CPU context in an internal buffer, instead of using the user-provided memory. Since this handle is valid, it can be used to co_switch to this execution context from another cothread. In multi-threaded applications, make sure to not switch non-cothread context across CPU cores, to prevent any conflict with OS scheduler.
I think it's less straight-forward but it's fine as long as there is a working example (with proper comments) for them.
I dug out the old code that used to come with standalone libco releases, and made PR #29.
In particular, we have:
test_args
demonstrates how to spawn a function that takes arguments as a co-routinetest_serialization
is an advanced example that demonstrates snapshotting and restoring program state by copying the contents of the coroutine stacks (not safe if your program makes heap allocations at runtime!)test_timing
is the aforementioned example/benchmark/smoke-testLet me know what you think.
I think they would be very helpful. Maybe I should also move my example to doc/examples/
and update the usage document? Or should I leave the usage document to @namandixit ?
I like the current state of usage.md
in this PR. I'll merge it.
I think the example in this PR is very similar to test_timing
in #29, and I'm worried it might be confusing to have both of them. If there's anything those new examples don't cover, I'd love to have your feedback on that PR.
Merged in a22bd9dba264e70ee7ea7dc2027af4b076890e43
If you don't mind though, I think it would be more helpful to also have a simple example file along with the usage document.