Skip to content

Commit 26ea227

Browse files
sunny-gfilmor
authored andcommitted
renames Schedule variants, adds reschedule macro
1 parent 04833dd commit 26ea227

File tree

3 files changed

+51
-65
lines changed

3 files changed

+51
-65
lines changed

rustler/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ pub mod dynamic;
4949
pub use crate::dynamic::TermType;
5050

5151
pub mod schedule;
52-
pub use crate::schedule::SchedulerFlags;
52+
pub use crate::schedule::{Schedule, SchedulerFlags};
5353
pub mod env;
5454
pub use crate::env::{Env, OwnedEnv};
5555
pub mod thread;

rustler/src/schedule.rs

Lines changed: 46 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,19 @@ pub enum SchedulerFlags {
1111
DirtyIo = ErlNifTaskFlags::ERL_NIF_DIRTY_JOB_IO_BOUND as isize,
1212
}
1313

14-
impl SchedulerFlags {
15-
#[inline]
16-
fn from(n: isize) -> Self {
17-
match n {
18-
_ if n == Self::Normal as isize => Self::Normal,
19-
_ if n == Self::DirtyCpu as isize => Self::DirtyCpu,
20-
_ if n == Self::DirtyIo as isize => Self::DirtyIo,
21-
_ => unreachable!(),
22-
}
23-
}
24-
}
25-
2614
pub fn consume_timeslice(env: Env, percent: i32) -> bool {
2715
let success = unsafe { rustler_sys::enif_consume_timeslice(env.as_c_arg(), percent) };
2816
success == 1
2917
}
3018

19+
/// Convenience macro for scheduling a future invokation of a NIF.
20+
#[macro_export]
21+
macro_rules! reschedule {
22+
($flags:expr, $($arg:expr),*) => (
23+
rustler::schedule::Schedule::from(($flags, $($arg,)*))
24+
)
25+
}
26+
3127
/// Convenience type for scheduling a future invokation of a NIF.
3228
///
3329
/// ## Usage:
@@ -38,76 +34,66 @@ pub fn consume_timeslice(env: Env, percent: i32) -> bool {
3834
///
3935
/// The second generic type defined should be the type of the return value.
4036
///
41-
/// Every other generic type is optional, but should reflect the non-`rustler`
42-
/// arguments provided to the NIF, in the same order.
37+
/// Every other generic type is optional, but should reflect the argument types
38+
/// of the scheduled NIF, in the same order.
4339
///
4440
/// ## Example:
4541
/// ```rust,ignore
4642
/// #[nif]
4743
/// fn factorial(input: u32, result: Option<u32>) -> Schedule<factorial, u32, u32, u32> {
4844
/// let result = result.unwrap_or(1);
4945
/// if input == 0 {
50-
/// Schedule::Result(result)
46+
/// Schedule::Return(result)
5147
/// } else {
52-
/// // alternatively `Schedule::Next2(std::marker::PhantomData, input - 1, result * input)`
53-
/// // alternatively `(input - 1, result * input).into()`
54-
/// Schedule::next2(input - 1, result * input)
48+
/// // alternatively `Schedule::Continue2(std::marker::PhantomData, SchedulerFlags::Normal, input - 1, result * input)`
49+
/// // alternatively `Schedule::continue2(SchedulerFlags::Normal, input - 1, result * input)`
50+
/// // alternatively `Schedule::from((SchedulerFlags::Normal, input - 1, result * input))`
51+
/// // alternatively `(SchedulerFlags::Normal, input - 1, result * input).into()`
52+
/// reschedule!(SchedulerFlags::Normal, input - 1, result * input)
5553
/// }
5654
/// }
5755
/// ```
5856
pub enum Schedule<N: crate::Nif, T, A = (), B = (), C = (), D = (), E = (), F = (), G = ()> {
5957
/// The final result type to return back to the BEAM.
60-
Result(T),
58+
Return(T),
6159
/// Single- and multiple-argument variants that should reflect the scheduled
6260
/// NIF's function signature.
63-
Next(PhantomData<N>, A),
64-
Next2(PhantomData<N>, A, B),
65-
Next3(PhantomData<N>, A, B, C),
66-
Next4(PhantomData<N>, A, B, C, D),
67-
Next5(PhantomData<N>, A, B, C, D, E),
68-
Next6(PhantomData<N>, A, B, C, D, E, F),
69-
Next7(PhantomData<N>, A, B, C, D, E, F, G),
61+
Continue(PhantomData<N>, SchedulerFlags, A),
62+
Continue2(PhantomData<N>, SchedulerFlags, A, B),
63+
Continue3(PhantomData<N>, SchedulerFlags, A, B, C),
64+
Continue4(PhantomData<N>, SchedulerFlags, A, B, C, D),
65+
Continue5(PhantomData<N>, SchedulerFlags, A, B, C, D, E),
66+
Continue6(PhantomData<N>, SchedulerFlags, A, B, C, D, E, F),
67+
Continue7(PhantomData<N>, SchedulerFlags, A, B, C, D, E, F, G),
7068
}
7169

7270
macro_rules! impl_funcs {
7371
($variant:ident $func_name:ident($($arg:ident : $ty:ty,)*)) => {
7472
impl<N: crate::Nif, T, A, B, C, D, E, F, G> Schedule<N, T, A, B, C, D, E, F, G> {
7573
#[allow(clippy::many_single_char_names)]
7674
#[inline]
77-
pub fn $func_name($($arg: $ty),*) -> Self {
78-
Self::$variant(PhantomData, $($arg),*)
75+
pub fn $func_name(flags: SchedulerFlags, $($arg: $ty),*) -> Self {
76+
Self::$variant(PhantomData, flags, $($arg),*)
7977
}
8078
}
8179

82-
impl<N: crate::Nif, T, A, B, C, D, E, F, G> From<($($ty),*)> for Schedule<N, T, A, B, C, D, E, F, G> {
80+
impl<N: crate::Nif, T, A, B, C, D, E, F, G> From<(SchedulerFlags, $($ty),*)> for Schedule<N, T, A, B, C, D, E, F, G> {
8381
#[allow(clippy::many_single_char_names)]
8482
#[inline]
85-
fn from(($($arg),*): ($($ty),*)) -> Self {
86-
Self::$func_name($($arg),*)
83+
fn from((flags, $($arg),*): (SchedulerFlags, $($ty),*)) -> Self {
84+
Self::$func_name(flags, $($arg),*)
8785
}
8886
}
8987
};
9088
}
9189

92-
impl<N: crate::Nif, T, A, B, C, D, E, F, G> Schedule<N, T, A, B, C, D, E, F, G> {
93-
#[inline]
94-
pub fn next(a: A) -> Self {
95-
Self::Next(PhantomData, a)
96-
}
97-
}
98-
99-
impl<N: crate::Nif, T, A, B, C, D, E, F, G> From<A> for Schedule<N, T, A, B, C, D, E, F, G> {
100-
#[inline]
101-
fn from(a: A) -> Self {
102-
Self::next(a)
103-
}
104-
}
105-
impl_funcs! { Next2 next2(a: A, b: B,) }
106-
impl_funcs! { Next3 next3(a: A, b: B, c: C,) }
107-
impl_funcs! { Next4 next4(a: A, b: B, c: C, d: D,) }
108-
impl_funcs! { Next5 next5(a: A, b: B, c: C, d: D, e: E,) }
109-
impl_funcs! { Next6 next6(a: A, b: B, c: C, d: D, e: E, f: F,) }
110-
impl_funcs! { Next7 next7(a: A, b: B, c: C, d: D, e: E, f: F, g: G,) }
90+
impl_funcs! { Continue continue1(a: A,) }
91+
impl_funcs! { Continue2 continue2(a: A, b: B,) }
92+
impl_funcs! { Continue3 continue3(a: A, b: B, c: C,) }
93+
impl_funcs! { Continue4 continue4(a: A, b: B, c: C, d: D,) }
94+
impl_funcs! { Continue5 continue5(a: A, b: B, c: C, d: D, e: E,) }
95+
impl_funcs! { Continue6 continue6(a: A, b: B, c: C, d: D, e: E, f: F,) }
96+
impl_funcs! { Continue7 continue7(a: A, b: B, c: C, d: D, e: E, f: F, g: G,) }
11197

11298
unsafe impl<N, T, A, B, C, D, E, F, G> NifReturnable for Schedule<N, T, A, B, C, D, E, F, G>
11399
where
@@ -124,10 +110,10 @@ where
124110
#[inline]
125111
unsafe fn into_returned(self, env: Env) -> NifReturned {
126112
macro_rules! branch {
127-
($($arg:tt),*) => (
113+
($flags:expr, $($arg:tt),*) => (
128114
NifReturned::Reschedule {
129115
fun_name: CStr::from_ptr(N::NAME as *const c_char).into(),
130-
flags: SchedulerFlags::from(N::FLAGS as isize),
116+
flags: $flags,
131117
fun: N::RAW_FUNC,
132118
args: vec![$($arg.encode(env).as_c_arg()),*],
133119
}
@@ -136,14 +122,14 @@ where
136122

137123
#[allow(clippy::many_single_char_names)]
138124
match self {
139-
Self::Result(res) => NifReturned::Term(res.encode(env).as_c_arg()),
140-
Self::Next(_, a) => branch!(a),
141-
Self::Next2(_, a, b) => branch!(a, b),
142-
Self::Next3(_, a, b, c) => branch!(a, b, c),
143-
Self::Next4(_, a, b, c, d) => branch!(a, b, c, d),
144-
Self::Next5(_, a, b, c, d, e) => branch!(a, b, c, d, e),
145-
Self::Next6(_, a, b, c, d, e, f) => branch!(a, b, c, d, e, f),
146-
Self::Next7(_, a, b, c, d, e, f, g) => branch!(a, b, c, d, e, f, g),
125+
Self::Return(res) => NifReturned::Term(res.encode(env).as_c_arg()),
126+
Self::Continue(_, flags, a) => branch!(flags, a),
127+
Self::Continue2(_, flags, a, b) => branch!(flags, a, b),
128+
Self::Continue3(_, flags, a, b, c) => branch!(flags, a, b, c),
129+
Self::Continue4(_, flags, a, b, c, d) => branch!(flags, a, b, c, d),
130+
Self::Continue5(_, flags, a, b, c, d, e) => branch!(flags, a, b, c, d, e),
131+
Self::Continue6(_, flags, a, b, c, d, e, f) => branch!(flags, a, b, c, d, e, f),
132+
Self::Continue7(_, flags, a, b, c, d, e, f, g) => branch!(flags, a, b, c, d, e, f, g),
147133
}
148134
}
149135
}
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
use rustler::schedule::Schedule;
1+
use rustler::{reschedule, Schedule, SchedulerFlags};
22

33
#[rustler::nif]
4-
fn scheduled_fac(input: u32, result: Option<u32>) -> Schedule<scheduled_fac, u32, u32, u32> {
4+
fn scheduled_fac<'a>(input: u32, result: Option<u32>) -> Schedule<scheduled_fac, u32, u32, u32> {
55
let result = result.unwrap_or(1);
66
if input == 0 {
7-
Schedule::Result(result)
7+
Schedule::Return(result)
88
} else {
9-
(input - 1, result * input).into()
9+
reschedule!(SchedulerFlags::Normal, input - 1, result * input)
1010
}
1111
}

0 commit comments

Comments
 (0)