1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
//! Lightweigh green threads & coroutines in stable Rust. //! //! # Getting started //! //! Add greenie to your `Cargo.toml`: //! ```toml //! [dependencies] //! greenie = "*" //! ``` //! //! Create greenie main function in `src/main.rs`: //! ```ignore //! use greenie::*; //! //! #[greenie_main] //! fn main() { //! //! } //! // Or you can invoke `create_main`: //! fn main() { //! create_main(|| { //! }); //! } //! //! ``` //! //! //! # Example //! Ping-pong program //! ```ignore //! use greenie::channel::*; //! //! use greenie::{greeny_main, Fiber}; //! #[greeny_main] //! fn main() { //! let chan_1 = Channel::<&'static str>::new(2); //! let chan_2 = Channel::<&'static str>::new(2); //! let fping = Fiber::new_capture( //! |chan_1, chan_2| { //! chan_1.send("ping"); //! println!("{}", chan_2.recv().unwrap()); //! chan_1.send("ping"); //! println!("{}", chan_2.recv().unwrap()); //! chan_1.send("ping"); //! println!("{}", chan_2.recv().unwrap()); //! }, //! (chan_1.clone(), chan_2.clone()), //! ); //! let fpong = Fiber::new_capture( //! |chan_1, chan_2| { //! chan_2.send("pong"); //! println!("{}", chan_1.recv().unwrap()); //! chan_2.send("pong"); //! println!("{}", chan_1.recv().unwrap()); //! chan_2.send("pong"); //! println!("{}", chan_1.recv().unwrap()); //! }, //! (chan_1.clone(), chan_2.clone()), //! ); //! //! fpong.start().unwrap(); //! fping.start().unwrap(); //! } //! ``` #![allow(dead_code, improper_ctypes)] #[macro_use] extern crate intrusive_collections; pub mod algorithm; pub mod common; pub mod ctx; pub mod fiber; pub mod generator; pub mod ptr; pub mod scheduler; pub use generator::generator_yield; pub use scheduler::{spawn_greenie, yield_thread}; pub use greenie_proc::{greenify, greeny_main}; /// Puts the current thread to sleep for at least the specified amount of time. /// /// The thread may sleep longer than the duration specified due to scheduling specifics or platform-dependent functionality. It will /// never sleep less. pub fn thread_sleep(duration: std::time::Duration) { let now = std::time::Instant::now(); while duration > now.elapsed() { crate::yield_thread(); } } use ctx::Context; pub use fiber::Fiber; pub use generator::*; /// Specify entry point for program that will use greenie. pub fn create_main(main_fn: fn()) -> ! { scheduler::RUNTIME.with(|rt| { let h = rt.get().spawn(|f, _| f(), (main_fn, ())); rt.get().main_ctx = h.thread(); rt.main_ctx.get().is_main = true; rt.get().run(); //unsafe { std::intrinsics::drop_in_place(rt.0) }; }); unreachable!() }